view tests/agcl/oldagsrc/y2ag.syn @ 21:1c9dac05d040

Add lint-style FALLTHROUGH annotations to fallthrough cases. (in the parse engine and thus the output code) Document this, because the old output causes warnings with gcc10.
author David A. Holland
date Mon, 13 Jun 2022 00:04:38 -0400
parents 13d2b8934445
children
line wrap: on
line source

{/*

YACC to AnaGram converter.
Copyright (c) Jerome T. Holland, 1993
All Rights Reserved.

Converts YACC files to AnaGram, attempting to preserve comments.
Does not convert semantic actions.

*/}


[
  line numbers
  nest comments
  parser file name = "#.cpp"
  parser name = y2ag
  sticky { name}
]


/*****

 Character Set Definitions

*****/

anything        = ~eof
backslash       = '\\'
c literal elem  = ~(single quote + double quote + backslash + eof)
digit           = '0-9'
dot             = '.'
double quote    = '"'
eof             =  -1 + 0 + 26
escapes         = 'n' + 'r' + 'b' + 't' + 'f'
letter          = 'a-z' + 'A-Z' + '_'
printing char   = 33..126
simple c char   = ~('$' + '{' + '}' + single quote + double quote + eof)
single quote    = '\''


/*****

 YACC file specification

*****/

grammar
 -> elc?,
    definition block,
    mark, elc?,
    c code block?,
    rule section,
    tail, eof

mark = "%%"

definition block
 -> definitions      ={if (size(config))
                         out << "\n[\n" << (char *) config << "]\n";}

/*****

 White space definitions

*****/

white
 -> ' ' + '\t' + '\v' + '\f' + '\r' + '\n'
 -> comment

comment
 -> comment text, "*/"                      =comments << "*/";

comment text
 -> "/*"                                    =comments << "/*";
 -> comment text, anything:x                =comments << x;

elc
 -> '\n' + '\v' + '\f', comment?        =reset(white),out << '\n',dump_comments("", "");
 -> ' ' + '\t', comment?                =reset(white), dump_comments("\t", "");
 -> comment                             =reset(white), dump_comments("", "");
 -> elc, '\n' + '\v' + '\f', comment?   =out << '\n', dump_comments("", "");
 -> elc, ' ' + '\t', comment?           =dump_comments("\t", "");

blc
 -> '\n' + '\v' + '\f':c, comment?      =reset(white), dump_comments("", "");
 -> ' ' + '\t':c, comment?              =reset(white) << c,dump_comments("", "");
 -> comment                             =reset(white),dump_comments("", "");
 -> blc, '\n' + '\v' + '\f':c, comment? =dump_comments("\t", "");
 -> blc, ' ' + '\t':c, comment?         =white << c, dump_comments("", "");

clc
 -> '\n' + '\v' + '\f':c, comment?      =reset(white),out << cs, cs = "", dump_comments("", "");
 -> ' ' + '\t':c, comment?              =reset(white) << c,dump_comments("", "");
 -> comment                             =reset(white),dump_comments("", "");
 -> clc, '\n' + '\v' + '\f':c, comment? =out << cs, cs = "",dump_comments("", "");
 -> clc, ' ' + '\t':c, comment?         =white << c, dump_comments("", "");

/*****

 Definition statements

*****/

definitions
 ->
 -> definitions, definition                 =dump_comments("\n","\n");

definition
 -> start, identifier, elc? ={
      out.printf("[ grammar token = %s ]\n",(char *) name);
      grammar_tag = "";
    }
 -> union, union text, elc?
 -> c code block
 -> token, print token list, elc?      =out << '\n';
 -> left, print prec list, blc?       =config << "}\n";
 -> right, print prec list, blc?      =config << "}\n";
 -> nonassoc, print prec list, blc?   =config << "}\n";
 -> type, type name, print token list,
     elc?                              =out << '\n';
 -> expect statement, elc?             =out << '\n';

union text
 -> '{', decl, '}'

decl
 -> {decl name | decl white | decl star | decl term}/...  =reset(name);

decl term
 -> ';' ={
  int decl_ndx = decl_dict << decl_name;
  int type_ndx = decl_dict << (char *) type_acc;
  decl_table[decl_ndx] = type_ndx;
  reset(type_acc);
  reset(name);
  *decl_name = 0;
 }

decl name
 -> name  =type_acc << (char *) decl_name, strcpy(decl_name, name), reset(name);

decl white
 -> white...  ={if (*decl_name) type_acc << (char *) decl_name << ' ', *decl_name = 0;}

decl star
 -> {'*'  =type_acc << (char *) decl_name << '*', *decl_name = 0;}...

expect statement
 -> "%expect", elc?, number:n =out.printf("/* expect %d unresolved conflicts */\n",n);

left
 -> {"%left" | "%<"},
      white?...                             =config << "  left {";

nonassoc
 -> {"%nonassoc" | "%binary" | "%2"},
      white?...                             =config << "  nonassoc {";

right
 -> {"%right" | "%>"},
      white?...                             =config << "  right {";

start
 -> "%start", white?...

token
 -> {"%token" | "%term" | "%0"},
     white?...

type
 -> "%type", white...            // =out << '(';

type name
 -> '<', white?..., name, white?...,
    '>', elc? =out << '(' << decl_dict[decl_table[decl_dict[name]]] << ") ", reset(name);

union
 -> "%union", white?...

print token list
 -> tag?, identifier                        =out << (char *) name, cs = ", ";

 -> print token list, elc, identifier  =out << cs << (char *) name;
 -> print token list, elc?, ',', elc?,
      identifier                            =out << cs << (char *) name;
 -> print token list, elc,
      number:n        =out.printf(" = %d\n",n);

print prec list
 -> tag?, identifier                        =config<< (char *) name, cs = ", ";

 -> print prec list, blc, identifier        =config << cs << (char *) name;
 -> print prec list, blc?, ',', blc?,
      identifier                            =config << cs << (char *) name;
 -> print prec list, blc,
      number:n                              =config.printf("/* = %d*/",n);

tag
 -> '<', elc?, identifier, elc?, '>', elc?


/*****

 Syntax to copy C code, watching for character constants, literal strings,
 comments and nested blocks, and picking up value stack references.

*****/

c code block
 -> "%{", c text, "%}",
      white?... =out << "\n{\n" << (char *) c_code << "\n}\n",reset(c_code);

action
 -> embedded c
 -> '=', white?..., embedded c

embedded c
 -> '{', c text, '}'

c text
 ->                                         =reset(c_code), rvflag = 0;
 -> c text, c char

c char           //c char represents the content of embedded c
 -> simple c char:x      =c_code << x;
 -> '$'                  =c_code << '$';
 -> c code comment
 -> '{', nested c text, '}'                 =c_code << '}';
 -> '\'', c literal character, '\''
 ->  literal string, '"'                    =c_code << '"';

c code comment
 -> c code comment text, "*/"               =c_code << "*/";

c code comment text
 -> "/*"                                    =c_code << "/*";
 -> c code comment text, anything:x         =c_code << x;

(int) number
 -> digit:d                                 =d - '0';
 -> number:n, digit:d                       =10*n + d - '0';

[ sticky {number}]

nested c text
 ->                                         =c_code << '{';
 -> nested c text, c char

c literal character
 -> 32..176 - '\\' :x                       =c_code << '\'' << x << '\'';
 -> '\\', octal digits

octal digits
 -> '0-7':x                                 =c_code << x;
 -> octal digits, '0-7':x                   =c_code << x;

literal string
  -> '"'                                    =c_code << '"';
  -> literal string, string character

string character
 -> 32..176 - '\\' -'"':x        =c_code << x;
 -> '\\', 32..176:x              =c_code << '\\' << x;


/*****

 Rules Section

*****/

rule section
 -> [production, elc?]...


production
 -> production head, complete rules, ';'   =output_r();

production head
 -> identifier, white?..., ':'  ={
      out << (char *) name << grammar_tag;
      grammar_tag = "";
      cs = "\n -> ";
      dump_comments("\t","");
    }

complete rules
 -> complete rule
 -> rule set continuation, complete rule

rule set continuation
 -> complete rules, '|'  =output_r(), out << "\n -> ",  cs = "";

complete rule
 -> rule
 -> rule, explicit precedence

rule
 -> clc?                                =out << cs, cs = "";
 -> rule name continuation, blc?
 -> rule literal continuation, blc?
 -> rule, action, blc?

rule name continuation
 -> rule, name        ={
      output_il();
      out.printf("%s%s",cs,(char *) name); cs = ", ";
 }
rule literal continuation
 -> rule, literal:x ={
      char *fmt = "%d";
      if (isprint(x)) fmt ="'%c'";
      reset(name).printf(fmt,x);
      output_il();
      out.printf("%s%s",cs,(char *) name); cs = ", ";
    }

explicit precedence
 -> explicit precedence head, blc
 -> explicit precedence head, blc?, action, blc?

explicit precedence head
 -> prec, identifier  =out.printf(" /* %prec %s */",(char *) name);

prec
 -> {"%prec" | "%="}, white?...  =dump_comments("\t","");

identifier
 -> name
 -> literal:x                     ={
      char *fmt = "%d";
      if (isprint(x)) fmt ="'%c'";
      reset(name).printf(fmt,x);
    }

(int) literal
 -> '\'', literal character:x, '\''         =x;
 -> '"', literal character:x, '"'           =x;

(int) literal character
 -> 32..176 - '\\'
 -> '\\', 'n' = '\n';
 -> '\\', 'r' = '\r';
 -> '\\', 'b' = '\b';
 -> '\\', 't' = '\b';
 -> '\\', 'f' = '\v';
 -> '\\', 32..176 - '0-7' - escapes :x      =x&037;
 -> '\\', octal number:x                    =x;

name
 -> letter+dot:x                            =reset(name) << x;
 -> name, letter+digit:x                    =name << x;
 -> name, dot                               =name << ' ';


(int) octal number
 -> '0-7':x                                 =x-'0';
 -> octal number:v, '0-7':x                 =8*v + x-'0';

tail
 ->
 -> mark, tail code                         =out << "\n}\n";

tail code
 ->                                         =out << "\n{\n";
 -> tail code, anything:x                   =out << x;


{
#include <ctype.h>
#include <stdio.h>
#include "charsink.h"
#include "strdict.h"

string_accumulator c_code(64000);
string_accumulator comments(10000);
string_accumulator name(100);
string_accumulator white(100);
string_accumulator config(1000);
string_accumulator type_acc(100);
string_dictionary decl_dict(100);

char decl_name[100] = "";
int decl_table[100];

output_file out;

char *cs;

char *type_string = "int AG_RTV;\n";


int rvflag;

char *grammar_tag = " $";

void dump_comments(char *ps, char *cs) {
  if (size(comments) == 0) return;
  out << (char *) white << ps << (char *) comments << cs;
  reset(comments);
}

void output_r(void) {
  char *rs = "";
  char *ts = "";
  if (size(c_code) == 0) return;
  out.printf(" ={%s%s%s}", ts,(char *) c_code,rs);
  reset(c_code);
}

void output_il(void) {
  char *rs = "";
  char *ts = "";
  if (size(c_code) == 0) return;
  out.printf("%s!{\n%s%s%s}", cs, ts, (char *) c_code,rs);
  reset(c_code);
  cs = ",\n   ";
}

void main(void) {
  y2ag();
}

}                                           // End of Embedded C