%{ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include <assert.h> #include "log.h" #include "taccutil.h" #include "sscanr.h" #include "debug.h" #include "mmalloc.h" /* This program parses a Coral66 source file, and walks the parse tree to output the source with consistent case and indentation. The input for this program must come from the "filter" program also in this directory. The grammar needs to be refactored a little; currently it parses anything starting with BEGIN as a single block unit; it needs to split those up into separate statements and keep an explicit stack of nested constructs. Note that the language uses ";" as a separator, not a terminator, so some statements require a terminating semicolon and some don't. Could make a refactored grammar a little tricky. */ /* This is the type of objects passed around as $1, $$ etc. */ #define USERTYPE char * #define RBRACE '}' /* Bug in tacc translation - } skipped OK in strings but not int consts */ #define SQUOTE 39 #define DQUOTE 34 int exit_flag = FALSE; int printing = TRUE; int ilev = 0; /* nested begin/end for now. Later use a stack */ int delayed_ilev = 0; extern int _debug; /* set to true for parser diags */ int label = FALSE; char *ProgName = "c66tohtml"; extern char **argv; extern int argc; int verbose = FALSE; void indent(int ilev) { while (ilev-- > 0) printf(" "); } void outs(char *line) { int i, c; static int soft = FALSE, outpos = 0; i = ilev*4; // while (i-- > 0) fputc(' ', stdout); for (;;) { c = (*line++)&255; if (c == '\0') break; if (c == '\n') { i = ilev*4; fputc('\n', stdout); outpos = 0; while (i-- > 0) {fputc(' ', stdout); outpos++;} ilev += delayed_ilev; delayed_ilev = 0; soft = TRUE; } else { if (soft && ((c == ';') || (c == '\n'))) { } else { if (c == ' ' && (outpos >= 72)/* && (outpos + strlen(line) > 78)*/) { fputc('\n', stdout); outpos = 0; i = ilev*4; while (i-- > 0) {fputc(' ', stdout); outpos++;} fputc(' ', stdout); fputc(' ', stdout); outpos += 2; } else { fputc(c, stdout); outpos++; } soft = FALSE; } } } } char *doubleup(char *text, int c) { char *s, *t; int ccount = 0; s = text; while (*s != '\0') if (*s++ == c) ccount += 1; t = s = stackmalloc(strlen(text)+ccount+1); if (s == NULL) { fprintf(stderr, "copyof: malloc fails - not enough room.\n"); exit(EXIT_FAILURE); } for (;;) { if (*text == c) *s++ = c; if ((*s++ = *text++) == '\0') break; } return(t); } char *formatf(char *s, ...) { /* Size the string by vfprint'ing it to /dev/null... */ /* then heapmalloc an appropriate area */ char *APPROPRIATE_STRING; va_list ap; va_start(ap, s); { static FILE *nullfile = NULL; int string_length; if (nullfile == NULL) nullfile = fopen("/dev/null", "w"); if (nullfile == NULL) { fprintf(stderr, "Major error - cannot open /dev/null\n"); fflush(stderr); exit(1); } string_length = vfprintf(nullfile, s, ap); /* fclose(nullfile); */ APPROPRIATE_STRING = tempheapmalloc(string_length+1); vsprintf(APPROPRIATE_STRING, s, ap); } va_end(ap); return(APPROPRIATE_STRING); } char *strlwr(char *orig) { char *s = orig; for (;;) { if (*s == '\0') break; if ((isalpha(*s)) && (isupper(*s))) *s = tolower(*s); s++; } return(orig); } %} /* Main cheats - it invokes the parsing routines explicitly, in order to reduce the size of the parse tree for a whole file. Also allows recovery of errors at useful boundaries */ main: "" { YYTYPE *subroot; void *stacktop; int i; if (strcmp(argv[argc-1], "-v") == 0) { argc -= 1; verbose = TRUE; } if (strcmp(argv[argc-1], "-d") == 0) { argc -= 1; _debug = TRUE; } if (strcmp(argv[argc-1], "-vd") == 0) { argc -= 1; _debug = TRUE; verbose = TRUE; } if (argc == 1) { yyin = fopen("test.ii", "r"); } else if (argc != 2) { fprintf(stderr, "syntax: c66tohtml infile.ii\n"); /* Let's just resume for now... */ yyin = fopen(argv[1], "r"); } else { yyin = fopen(argv[1], "r"); } if (yyin == NULL) { fprintf(stderr, "c66tohtml: cannot open input\n"); exit(EXIT_FAILURE); } fprintf(stderr, "%s: processing %s\n", argv[0], argv[1] == NULL ? "test.ii" : argv[1]); if (verbose) fprintf(stderr, "Starting\n"); for (;;) { stacktop = stackmark(); if (Statementlist_parse(&subroot)) { execute_parsetree(subroot); } else { return(FALSE); } stackrelease(stacktop); if (exit_flag) return(TRUE); //printf("\n"); } } ; Actual: <Expression> { $$ = $1; } | <Wordreference> { $$ = $1; } | <Destination> { $$ = $1; } | <Name> { $$ = $1; }; Actuallist: <Actual> <RestofActuallist> { $$ = formatf("%s%s", $1, $2); }; RestofActuallist: "," <Actual> <RestofActuallist> { $$ = formatf(", %s%s", $2, $3); } | "" { $$ = formatf(""); }; Addoperator: "+" { /* NOTE: No void choice. Compare against <sign> ... */ $$ = formatf(" + "); } | "\-" { $$ = formatf(" - "); }; Alternative: <Statement> { $$ = $1; }; Answerspec: <Numbertype> { $$ = $1; } | "" { /* Void */ $$ = formatf(""); }; Answerstatement: "ANSWER" <Expression> { $$ = formatf("'ANSWER' %s", $2); }; Arraydec: <Numbertype> "ARRAY" <Arraylist> <Presetlist> { $$ = formatf("%s'ARRAY' %s%s", $1, $3, $4); }; Arrayitem: <Idlist> "\[" <Sizelist> "\]" { $$ = formatf("%s[ %s ]", $1, $3); }; Arraylist: <Arrayitem> <RestofArraylist> { $$ = formatf("%s%s", $1, $2); }; RestofArraylist: "," <Arrayitem> <RestofArraylist> { $$ = formatf(", %s%s", $2, $3); } | "" { $$ = formatf(""); }; Assignmentstatement: <Variable> ":=" <Expression> { $$ = formatf("%s := %s", $1, $3); } | <Macrocall> ":=" <Expression> { $$ = formatf("%s := %s", $1, $3); }; Base: "\(" <Id> "\)" { $$ = formatf("(%s)", $2); } | <Id> "\[" <Signedinteger> "\]" { $$ = formatf("%s[%s]", $1, $3); }; Bitposition: <Integer> { $$ = $1; }; Block: "BEGIN" { /* <Declist> ";" <Statementlist> "END" */ $$ = formatf("'BEGIN'"); delayed_ilev += 1; }; Booleanword: <Typedprimary> <RestofBooleanexpr> { $$ = formatf("%s%s", $1, $2); }; RestofBooleanexpr: <Boolop> <Typedprimary> <RestofBooleanexpr> { $$ = formatf("%s%s%s", $1, $2, $3); } | "" { $$ = formatf(""); }; Boolop: "DIFFER" { $$ = formatf(" 'DIFFER' "); } | "UNION" { $$ = formatf(" 'UNION' "); } | "MASK" { $$ = formatf(" 'MASK' "); } | "SRL" { $$ = formatf(" 'SRL' "); } | "SLL" { $$ = formatf(" 'SLL' "); }; OldBooleanword: <BooleanwordA> { } | <BooleanwordC> "DIFFER" <BooleanwordD> { }; BooleanwordA: <BooleanwordB> { } | <BooleanwordD> "UNION" <BooleanwordE> { }; BooleanwordB: <BooleanwordE> "MASK" <Typedprimary> { }; BooleanwordC: <Booleanword> { } | <Typedprimary> { }; BooleanwordD: <BooleanwordA> { } | <Typedprimary> { }; BooleanwordE: <BooleanwordB> { /* Hmmm... 3 and 6 are an infinite loop ... */} | <Typedprimary> { }; Bracketedcomment: "\([^\)]*\)" { /* ( any sequence of characters in which round brackets are matched ) */ /* TO DO: Add nesting. */ $$ = formatf("%s", @1.text); } | "" { $$ = formatf(""); }; Codesequence: "<[^>]*>" { /* defined in a particular implementation */ /* For example, machine code */ $$ = formatf("%s", @1.text); }; Codestatement: "CODE" "BEGIN" <Codesequence> "END" <endtag> { $$ = formatf("'CODE' 'BEGIN' %s 'END'%s", $3, $4); }; Commentsentence: "COMMENT" "[^;]*" { /* any sequence of characters not including a semi-colon ; * /* TO DO: Allow newlines. Steal code from Algol60 grammar */ $$ = formatf("'COMMENT' %s", @2.text); }; clines: "[^;]*" "$" <clines> { $$ = formatf("%s\n%s", @1.text, $3); } | "" { $$ = formatf(""); }; Commoncommunicator: <exttype> "\(" <Commonitemlist> "\)" { $$ = formatf("%s(%s)", $1, $3); }; exttype: "COMMON" { $$ = formatf("'COMMON' "); } | "EXTERNAL" { $$ = formatf("'EXTERNAL' "); }; Commonitem: <Datadec> { $$ = $1; } | <Overlaydec> { $$ = $1; } | <Placespec> { $$ = $1; } | <Procedurespec> { /* removed Void alternative */ $$ = $1; } | <Commentsentence> { $$ = $1; }; Commonitemlist: <Commonitem> ";" <RestofCommonitemlist> { $$ = formatf("%s; %s", $1, $3); }; RestofCommonitemlist: <Commonitem> ";" <RestofCommonitemlist> { $$ = formatf("%s; %s", $1, $3); } | "" { $$ = formatf(""); }; Comparator: "=" { $$ = formatf(" = "); } | ">=" { $$ = formatf(" >= "); } | ">" { $$ = formatf(" > "); } | "<=" { $$ = formatf(" <= "); } | "<>" { $$ = formatf(" <> "); } | "<" { $$ = formatf(" < "); }; Comparison: <Simpleexpression> <Comparator> <Simpleexpression> { $$ = formatf("%s%s%s", $1, $2, $3); }; Compoundstatement: "BEGIN" { /* <Statementlist> "END" */ $$ = formatf("'BEGIN'"); delayed_ilev += 1; }; Condition: <SubCondition> <RestofCondition> { $$ = formatf("%s%s", $1, $2); }; RestofCondition: "OR" <SubCondition> <RestofCondition> { $$ = formatf(" 'OR' %s%s", $2, $3); } | "" { $$ = formatf(""); }; Conditionalexpression: "IF" <Condition> "THEN" <Expression> "ELSE" <Expression> { $$ = formatf("'IF' %s 'THEN' %s 'ELSE' %s", $2, $4, $6); }; Conditionalstatement: "IF" <Condition> "THEN" <LabelledStatement> <RestofConditionalstatement> { if ((strncmp($4, "'BEGIN'", 7) == 0) || (strncmp($5, "'BEGIN'", 7) == 0)) { $$ = formatf("'IF' %s 'THEN' %s%s\n", $2, $4, $5); } else { $$ = formatf("'IF' %s 'THEN'\n %s%s", $2, $4, $5); } }; RestofConditionalstatement: "ELSE" <Alternative> { $$ = formatf("\n'ELSE'\n %s", $2); } | "" { $$ = formatf(""); }; Constant: <Number> { $$ = $1; } | <Addoperator> <Number> { $$ = formatf("%s%s", $1, $2); } | <Expression> { /* ONLY IF ANY <Id>s IN <Expression> ARE ALREADY DEFINED AS CONSTANT SYMBOLS */ $$ = $1; }; Constantlist: <Group> <RestofConstantlist> { $$ = formatf("%s%s", $1, $2); }; RestofConstantlist: "," <Group> <RestofConstantlist> { $$ = formatf(", %s%s", $2, $3); } | "" { $$ = formatf(""); }; Datadec: <Numberdec> { $$ = $1; } | <Arraydec> { $$ = $1; } | <Tabledec> { $$ = $1; }; Dec: <Datadec> { $$ = $1; } | <Overlaydec> { $$ = $1; } | <Switchdec> { $$ = $1; } | <Proceduredec> { $$ = $1; }; Declist: <Dec> <RestofDeclist> { $$ = formatf("%s%s", $1, $2); }; RestofDeclist: ";" <Dec> <RestofDeclist> { $$ = formatf("; %s%s", $2, $3); } | "" { $$ = formatf(""); }; Destination: <Label> { $$ = $1; } | <Switch> "\[" <Index> "\]" { $$ = formatf("%s[%s]", $1, $3); }; Digit: "[0-9]" { /* 0 1 2 3 4 5 6 7 8 9 */ $$ = formatf("%s", @1.text); }; Digitlist: "[0-9][0-9]*" { /* <Digit> <RestofDigitlist> */ $$ = formatf("%s", @1.text); }; Dimension: <Lowerbound> ":" <Upperbound> { $$ = formatf("%s : %s", $1, $3); }; Dummystatement: <?term><!eof> { /* void */ $$ = formatf(""); }; term: ";" { $$ = formatf(";"); } | "END" <endtag> { $$ = formatf("'END'%s", $2); } | "ELSE" { $$ = formatf("'ELSE'"); }; likesemi: ";" { $$ = formatf(";"); } | <?term> { /* Don't eat END or ELSE */ $$ = formatf("\n"); }; Elementdec: <Id> <Numbertype> <Wordposition> { $$ = formatf("%s%s%s", $1, $2, $3); } | <Id> <Partwordtype> <Wordposition> "," <Bitposition> { $$ = formatf("%s%s%s, %s", $1, $2, $3, $5); }; Elementdeclist: <Elementdec> <RestofElementdeclist> { $$ = formatf("%s%s", $1, $2); }; RestofElementdeclist: ";" <Elementdeclist> { $$ = formatf("; %s", $2); } | "" { $$ = formatf(""); }; Elementpresetlist: "PRESET" <Constantlist> { $$ = formatf("'PRESET' %s", $2); } | "" { /* Void */ $$ = formatf(""); }; Elementscale: "\(" <Totalbits> "," <Fractionbits> "\)" { $$ = formatf("(%s, %s)", $2, $4); } | "\(" <Totalbits> "\)" { $$ = formatf("(%s)", $2); }; Endcomment: <Id> { $$ = $1; }; Expression: <Unconditionalexpression> { $$ = $1; } | <Conditionalexpression> { $$ = $1; }; Factor: <Primary> <!Boolop> { $$ = $1; } | <Booleanword> { $$ = $1; }; Forelement: <Expression> "WHILE" <Condition> { $$ = formatf("%s 'WHILE' %s", $1, $3); } | <Expression> "STEP" <Expression> "UNTIL" <Expression> { $$ = formatf("%s 'STEP' %s 'UNTIL' %s", $1, $3, $5); } | <Expression> { /* re-factor this! */ $$ = $1; }; Forlist: <Forelement> <RestofForlist> { $$ = formatf("%s%s", $1, $2); }; RestofForlist: "," <Forelement> <RestofForlist> { $$ = formatf(", %s%s", $2, $3); } | "" { $$ = formatf(""); }; Formalpair: <Id> ":" <Id> { $$ = formatf("%s:%s", $1, $3); }; Formalpairlist: <Formalpair> <RestofFormalpairlist> { $$ = formatf("%s%s", $1, $2); }; RestofFormalpairlist: "," <Formalpair> <RestofFormalpairlist> { $$ = formatf(", %s%s", $2, $3); } | "" { $$ = formatf(""); }; Forstatement: "FOR" <Wordreference> ":=" <Forlist> "DO" <Statement> { $$ = formatf("'FOR' %s := %s 'DO' %s", $2, $4, $6); }; Fractionbits: <Signedinteger> { $$ = $1; }; Gotostatement: "GOTO" <Destination> { $$ = formatf("'GOTO' %s", $2); }; Group: <Constant> { $$ = $1; } | "\(" <Constantlist> "\)" { $$ = formatf("(%s)", $2); } | "" { /* Void */ $$ = formatf(""); }; Id: "[a-z][_a-z0-9]*" { /* <Letter> <Letterdigitstring> */ $$ = formatf("%s", @1.text); }; Idlist: <Id> <RestofIdlist> { $$ = formatf("%s%s", $1, $2); }; RestofIdlist: "," <Idlist> { $$ = formatf(", %s", $2); } | "" { $$ = formatf(""); }; Index: <Expression> { $$ = $1; }; Integer: <Digitlist> { $$ = $1; } | "HEX" "\(" <Hexlist> "\)" { $$ = formatf("'HEX'(%s)", $3); } | "OCTAL" "\(" <Octallist> "\)" { $$ = formatf("'OCTAL'(%s)", $3);} | "LITERAL" "\(" "." "\)" { /* printing character */ $$ = formatf("'LITERAL'(%s)", @3.text); }; Hexlist: "[a-f0-9][a-f0-9]*" { $$ = formatf("%s", @1.text); }; Label: <Id> { $$ = $1; }; Labellist: <Label> <RestofLabellist> { $$ = formatf("%s%s", $1, $2); }; RestofLabellist: "," <Labellist> { $$ = formatf(", %s", $2); } | "" { $$ = formatf(""); }; Length: <Integer> { $$ = $1; }; Letter: "[a-z]" { /* a b c d e f g h i j k l m n o p q r s t u v w x y z */ $$ = formatf("%s", @1.text); }; Letterdigitstring: "[a-z0-9]*" { /* not needed now - see <Id> */ /* <Letter> <Letterdigitstring> */ /* <Digit> <Letterdigitstring> */ /* Void */ $$ = formatf("%s", @1.text); }; Lowerbound: <Signedinteger> { $$ = $1; }; Macrobody: "[^\"]*" { /* any sequence of characters in which string quotes are matched */ /* TO DO: match string quotes */ $$ = formatf("%s", @1.text); }; Macrocall: <Macroname> "\(" <Macrostringlist> "\)" { $$ = formatf("%s(%s)", $1, $3); // MACRO!!! EXPAND IT!!! } | <Macroname> <!lbrack> { $$ = $1; }; Macrodefinition: "DEFINE" <Macroname> "\"" <Macrobody> "\"" ";" { $$ = formatf("'DEFINE' %s %c%s%c;", $2, DQUOTE, $4, DQUOTE); } | "DEFINE" <Macroname> "\(" <Idlist> "\)" "\"" <Macrobody> "\"" ";" { $$ = formatf("'DEFINE' %s(%s) %c%s%c;", $2, $4, DQUOTE, $7, DQUOTE); }; Macrodeletion: "DELETE" <Macroname> ";" { $$ = formatf("'DELETE' %s;", $2); }; Macroname: <Id> { $$ = $1; }; Macrostring: "[^\)]*" { /* any sequence of characters in which commas are protected by round or square brackets and in which such brackets are properly matched and nested */ /* TO DO: just about everything ... */ $$ = formatf("%s", @1.text); }; Macrostringlist: <Macrostring> <RestofMacrostringlist> { $$ = formatf("%s%s", $1, $2); }; RestofMacrostringlist: "," <Macrostring> <RestofMacrostringlist> { $$ = formatf(", %s%s", $2, $3); } | "" { $$ = formatf(""); }; Multoperator: "\*" { $$ = formatf(" * "); } | "/" { $$ = formatf(" / "); }; Name: <Id> { $$ = $1; }; Number: <Real> { $$ = $1; } | <Integer> { $$ = $1; }; Numberdec: <Numbertype> <Idlist> <Presetlist> { $$ = formatf("%s%s%s", $1, $2, $3); }; Numbertype: "FLOATING" { $$ = formatf("'FLOATING' "); } | "FIXED" <Scale> { $$ = formatf("'FIXED' %s", $2); } | "LONGINTEGER" { $$ = formatf("'LONG' 'INTEGER' "); } | "INTEGER" { $$ = formatf("'INTEGER' "); } | "CONSTANT" { $$ = formatf("'CONSTANT' "); } | "BYTE" { $$ = formatf("'BYTE' ");}; Octaldigit: "[0-7]" { /* 0 1 2 3 4 5 6 7 */ $$ = formatf("%s", @1.text); }; Octallist: "[0-7][0-7]*" { /* Octaldigit Octalist */ /* Octaldigit */ $$ = formatf("%s", @1.text); }; Overlaydec: "OVERLAY" <Base> "WITH" <Datadec> { $$ = formatf("'OVERLAY' %s 'WITH' %s", $2, $4); }; Parameterspec: "VALUE" <Formalpairlist> { $$ = formatf("'VALUE' %s", $2); } | "LOCATION" <Formalpairlist> { $$ = formatf("'LOCATION' %s", $2); } | <Specifier> <Idlist> { $$ = formatf("%s%s", $1, $2); } | <Tablespec> { $$ = $1; } | <Procedurespec> { $$ = $1; }; Parameterspeclist: <Parameterspec> <RestofParameterspeclist> { $$ = formatf("%s%s", $1, $2);}; RestofParameterspeclist: ";" <Parameterspeclist> { $$ = formatf("; %s", $2); } | "" { $$ = formatf(""); }; Partword: <Id> "\[" <Index> "\]" { $$ = formatf("%s[%s]", $1, $3); } | "BITS" "\[" <Totalbits> "," <Bitposition> "\]" <Typedprimary> { $$ = formatf("'BITS'[%s, %s]%s", $3, $5, $7); }; Partwordreference: <Id> "\[" <Index> "\]" { $$ = formatf("%s[%s]", $1, $3); } | "BITS" "\[" <Totalbits> "," <Bitposition> "\]" <Wordreference> { $$ = formatf("'BITS'[%s, %s]%s", $3, $5, $7); }; Partwordtype: <Elementscale> { $$ = $1; } | "UNSIGNED" <Elementscale> { $$ = formatf("'UNSIGNED' %s", $2); }; Placespec: "LABEL" <Idlist> { $$ = formatf("'LABEL' %s", $2); } | "SWITCH" <Idlist> { $$ = formatf("'SWITCH' %s", $2); }; Presetlist: ":=" <Constantlist> { $$ = formatf(" := %s", $2); } | "" { /* Void */ $$ = formatf(""); }; Primary: <Untypedprimary> { $$ = $1; } | <Typedprimary> { $$ = $1; }; Procedurecall: <Id> "\(" <Actuallist> "\)" <!ass> { $$ = formatf("%s(%s)", $1, $3);} | <Id> <!lbrack> <!ass> { $$ = $1; }; Proceduredec: <Answerspec> <Recursive> <Procedureheading> <?term> { /* ";" <Statement> */ $$ = formatf("%s%s%s", $1, $2, $3); }; Recursive: "RECURSIVE" { $$ = formatf("'RECURSIVE' "); } | "PROCEDURE" { $$ = formatf("'PROCEDURE' "); }; Procedureheading: <Id> "\(" <Parameterspeclist> "\)" { $$ = formatf("%s(%s)", $1, $3); } | <Id> { $$ = $1; }; Procedurespec: <Answerspec> "PROCEDURE" <Procparamlist> { $$ = formatf("%s'PROCEDURE' %s", $1, $3); /* No RECURSIVE? */}; Procparameter: <Id> "\(" <Typelist> "\)" { $$ = formatf("%s(%s)", $1, $3); } | <Id> { $$ = $1; }; Procparamlist: <Procparameter> <RestofProcparamlist> { $$ = formatf("%s%s", $1, $2); }; RestofProcparamlist: "," <Procparameter> <RestofProcparamlist> { $$ = formatf(", %s%s", $2, $3); } | "" { $$ = formatf(""); }; Real: <Digitlist> "\." <Digitlist> <subten> <Signedinteger> { $$ = formatf("%s.%s%s%s", $1, $3, $4, $5); } | <Digitlist> "\." <Digitlist> { $$ = formatf("%s.%s", $1, $3); } | <Digitlist> <subten> <Signedinteger> { $$ = formatf("%s%s%s", $1, $2, $3); } | <subten> <Signedinteger> <!Id> <!lbrack> { /* AMBIGUOUS PARSE: "e1" could be <Real> *or* <Id> */ $$ = formatf("%s%s", $1, $2); } | "OCTAL" "\(" <Octallist> "\." <Octallist> "\)" { $$ = formatf("'OCTAL'(%s.%s)", $3, $5); }; subten: "@" { /* subscript 10 */ $$ = formatf("@"); } | "e" { $$ = formatf("E"); }; lbrack: "\(" { $$ = formatf("("); } | "\[" { $$ = formatf("["); }; Scale: "\(" <Totalbits> "," <Fractionbits> "\)" { $$ = formatf("(%s, %s)", $2, $4); }; Sign: "+" { $$ = formatf("+"); } | "\-" { $$ = formatf("-"); } | "" { /* Void */ $$ = formatf(""); }; Signedinteger: <Integer> { $$ = $1; } | <Addoperator> <Integer> { /* Not <sign>??? */ $$ = formatf("%s%s", $1, $2); }; Simpleexpression: <Term> <RestofSimpleexpression> { $$ = formatf("%s%s", $1, $2); } | <Addoperator> <Term> <RestofSimpleexpression> { /* note allows initial +/- but not a <sign> ??? */ $$ = formatf("%s%s%s", $1, $2, $3); }; RestofSimpleexpression: <Addoperator> <Term> <RestofSimpleexpression> { $$ = formatf(" %s %s%s", $1, $2, $3); } | <!Boolop> "" { $$ = formatf(""); }; Sizelist: <Dimension> "," <Dimension> { $$ = formatf("%s, %s", $1, $3); } | <Dimension> { $$ = $1; }; Specifier: "VALUE" <Numbertype> { $$ = formatf("'VALUE' %s", $2); } | "LOCATION" <Numbertype> { $$ = formatf("'LOCATION' %s", $2); } | <Numbertype> "ARRAY" { $$ = formatf("%s'ARRAY' ", $1); } | "LABEL" { } | "SWITCH" { }; Specimen: "ALPHA" <Sign> { $$ = formatf("'ALPHA'%s", $2); /* WHERE IS THIS USED??? */ } | "BETA" <Sign> { $$ = formatf("'BETA'%s", $2); }; Simplestatement: <Assignmentstatement> { $$ = $1; } | <Gotostatement> { $$ = $1; } | <Procedurecall> { $$ = $1; } | <Answerstatement> { $$ = $1; } | <Codestatement> { $$ = $1; } | <Compoundstatement> { $$ = $1; } | <Block> { /* Removed <Dummystatement> */ $$ = $1; }; LabelledStatement: <Labels> <Simplestatement> { $$ = formatf("%s%s", $1, $2); }; Labels: <Label> <!ass> ":" <Labels> { $$ = formatf("%s: %s", $1, $4); } | "" { $$ = formatf(""); }; ass: ":=" { $$ = formatf(" := "); }; Statement: <LabelledStatement> { $$ = $1; } | <Conditionalstatement> { $$ = $1; } | <Forstatement> { $$ = $1; } | <Commentsentence> { $$ = $1; } ; endtag: <!else> "[^;]*" { $$ = formatf(" %s", @2.text); } | "" { $$ = formatf(""); }; else: "ELSE" { }; Statementlist: <eof> { exit_flag = TRUE; } | "$" { $$ = formatf("\n"); outs($$); } | <Labels> ";" { $$ = formatf("%s;\n", $1); outs($$); } | "BEGIN" { /* Breaking down compound statements... */ $$ = formatf("'BEGIN'\n"); delayed_ilev += 1; outs($$); } | "END" "ELSE" "BEGIN" { $$ = formatf("'END' 'ELSE' 'BEGIN'\n"); ilev -= 1; outs($$); ilev += 1; } | "END" "ELSE" <Alternative> { $$ = formatf("\n'END' 'ELSE' %s", $3); ilev -= 1; outs($$); } | "END" <endtag> { $$ = formatf("\n'END'%s", $2); ilev -= 1; outs($$); } | <Macrodefinition> { $$ = formatf("%s\n", $1); outs($$); } | <Macrodeletion> { $$ = formatf("%s\n", $1); outs($$); } | "INCLUDE" "\"[^\"]*\";" { $$ = formatf("\n'INCLUDE' %s\n", @2.text); outs($$); } | <Dec> ";" <Bracketedcomment> { $$ = formatf("%s;%s\n", $1, $3); outs($$); } | <Statement> <likesemi> <Bracketedcomment> { /* break out into C loop to reduce parse-tree size */ /* <RestofStatementlist> */ $$ = formatf("%s%s%s\n", $1, $2, $3); outs($$); } | <Commoncommunicator> { /* NOT followed by semi */ $$ = formatf("%s\n", $1); } | "[^;]*;" { fprintf(stdout, "* Syntax? '%s'\n", @1.text); } | ".*END" { fprintf(stdout, "* Syntax? '%s'\n", @1.text); } | ".*ELSE" { fprintf(stdout, "* Syntax? '%s'\n", @1.text); } | ".*\)" { fprintf(stdout, "* Syntax? '%s'\n", @1.text); } | ".*" <eof> { fprintf(stdout, "* Syntax? '%s'\n", @1.text); } | ".*" { fprintf(stdout, "* Syntax? '%s'\n", @1.text); }; RestofStatementlist: ";" <Statement> <RestofStatementlist> { /* currently this phrase is never used */ $$ = formatf("; %s%s", $2, $3); } | "" { $$ = formatf(""); }; String: "\"[^\"]*\"" { /* " sequence of characters with quotes matched " */ $$ = formatf("%s", @1.text); }; SubCondition: <Comparison> <RestofSubcondition> { $$ = formatf("%s%s", $1, $2); }; RestofSubcondition: "AND" <Comparison> <RestofSubcondition> { $$ = formatf(" 'AND' %s%s", $2, $3); } | "" { $$ = formatf(""); }; Switch: <Id> { $$ = $1; }; Switchdec: "SWITCH" <Switch> ":=" <Labellist> { $$ = formatf("'SWITCH' %s := %s", $2, $4); }; Tabledec: "TABLE" <Id> "\[" <Width> "," <Length> "\]" <Tablerest> { /* Careful... TACC limitation of 9 items in phrase */ $$ = formatf("'TABLE' %s[%s, %s]%s", $2, $5, $7, $8); }; Tablerest: "\[" <Elementdeclist> <Elementpresetlist> "\]" <Presetlist> { $$ = formatf("[%s%s]%s", $2, $3, $5); }; Tablespec: "TABLE" <Id> "\[" <Width> "," <Length> "\]\[" <Elementdeclist> "\]" { $$ = formatf("'TABLE' %s[%s, %s] [%s]", $2, $4, $6, $8); }; Term: <Factor> <RestofTerm> { $$ = formatf("%s%s", $1, $2); }; RestofTerm: <Multoperator> <Factor> <RestofTerm> { $$ = formatf(" %s %s%s", $1, $2, $3); } | <!Boolop> "" { $$ = formatf(""); }; Totalbits: <Integer> { $$ = $1; }; Type: <Specifier> { $$ = $1; } | "TABLE" { $$ = formatf("'TABLE' "); } | <Answerspec> "PROCEDURE" { $$ = formatf("%s'PROCEDURE' ", $1); }; Typedprimary: <Procedurecall> { $$ = $1; } | <Macrocall> { $$ = $1; } | <Wordreference> { $$ = $1; } | <Partword> { $$ = $1; } | "LOCATION" "\(" <Wordreference> "\)" { $$ = formatf("'LOCATION'(%s)", $3); } | <Numbertype> "\(" <Expression> "\)" { $$ = formatf("%s(%s)", $1, $3); } | <Integer> { $$ = $1; }; Typelist: <Type> <RestofTypelist> { $$ = formatf("%s%s", $1, $2); }; RestofTypelist: "," <Type> <RestofTypelist> { $$ = formatf(", %s%s", $2, $3); } | "" { $$ = formatf(""); }; Unconditionalexpression: <Simpleexpression> { $$ = $1; } | <String> { $$ = $1; }; Untypedprimary: <Real> { $$ = $1; } | "\(" <Expression> "\)" { $$ = formatf("(%s)", $2); }; Upperbound: <Signedinteger> { $$ = $1; }; Variable: <Wordreference> { $$ = $1;} | <Partwordreference> { $$ = $1; }; Width: <Integer> { $$ = $1; }; Wordposition: <Signedinteger> { $$ = $1; }; Wordreference: <Id> "\[" <Index> "," <Index> "\]" { /* inefficiently factored grammar */ $$ = formatf("%s[%s, %s]", $1, $3, $5); } | <Id> "\[" <Index> "\]" { $$ = formatf("%s[%s]", $1, $3); } | <Macrocall> { $$ = $1; } | <Id> { $$ = $1; } | "\[" "\]" { $$ = formatf("[]"); }; %{ extern int debug(const char *fmt, ...); extern int debug_enter(const char *fmt, ...); extern int debug_exit(const char *fmt, ...); extern FILE *yyin; int eof_parse(YYTYPE **p) { int c; c = fgetc(yyin); if (c == EOF) { return(TRUE); } ungetc(c, yyin); return(FALSE); } int setdebug_parse(YYTYPE **p) { _debug = TRUE; return(TRUE); } int candebug_parse(YYTYPE **p) { _debug = FALSE; return(TRUE); } %}