Mercurial > ~dholland > hg > ag > index.cgi
view tests/agcl/oldagsrc/bciastp.syn @ 8:ec2b657edf13
Add explicit lint-comment-style fallthrough annotations.
GCC now assumes that if you don't have these you're making a mistake,
which is annoying.
XXX: This changeset updates the AG output files only (by hand) and is
XXX: abusive - rebuilding them will erase the change. However, I need
XXX: to get things to build before I can try to get AG to issue the
XXX: annotations itself, so this seems like a reasonable expedient.
author | David A. Holland |
---|---|
date | Mon, 30 May 2022 23:51:43 -0400 |
parents | 13d2b8934445 |
children |
line wrap: on
line source
{ /* BCIAST.SYN Compiler for Byte Code Interpreter (using parse tree) Copyright (c) 1997 Parsifal Software, All Rights Reserved. The expression syntax is borrowed from C but with the addition of the FORTRAN exponentiation operator (**). The cast, increment, and decrement operators are not implemented, nor are operations that are defined only for integers: Bitwise logical operators: &, |, ^, ~, &=, |=, ^= Remainder operators: %, %= Shift operators: <<, >>, >>=, <<= The supported operations are: Assignment operators: =, +=, -=, *=, /= Conditional expressions: ? : Logical operators: !, &&, || Comparison operators: ==, !=, <, <=, >, >= Binary arithmetic operators: +, -, *, / Exponentiation: ** Unary arithmetic operators: +, - Parentheses Built-in functions LOG, EXP All arithmetic is double precision floating point. Statements may include expression statements, blocks, if/else statements or while statements, following the rules of C. The statement syntax has been written to avoid the conventional if/else ambiguity. There are no declarations. All variables are presumed to be double. Input strings may contain any number of statements. White space may be used freely, including both C and C++ style comments. vmParse makes the following external calls: void pushChar(int character); Push the specified character onto a character stack. int locateVariable(int nameLength); Pop the last nameLength characters from the character stack and, treating them as the name of a variable, return an index into the variable array. Overrides for macros defined by AnaGram, such as SYNTAX_ERROR are included in VMDEFS.H VMPT.SYN is compiled with the AnaGram parser generator yielding VMPT.H and VMPT.CPP. To build VMPT, compile and link VMPT.CPP, VMDEMO.CPP and PTREE.CPP with your C++ compiler. For information about AnaGram, visit http://www.parsifalsoft.com. */ #include "bciast.h" #include "agstk.h" // Defines AgStack<Object> #include "agstr.h" // Defines AgString et al #include <math.h> // for pow() #include "ptree.h" //typedef AgStack<Statement *> StatementList; } // -- CONFIGURATION SECTION ---------------------------- [ disregard white space lexeme {real, name} pointer input parser name = astParse parser file name = "#.cpp" reentrant parser wrapper {AgStack<Statement *>, AgString} // Put the following in the parser control block for use during parsing extend pcb { // Maps symbol names to variables // AgSharedStringDictionary symbolDictionary; AbstractSyntaxTree *ast; // Temporary space to accumulate identifiers while parsing AgString charStack; } ] /* * Mark input string with $ to indicate it is the "grammar token", * that is, the whole of the input we're intending to parse. */ (Program *) input string $ -> statements:s, eof = PCB.ast->makeProgram(s); /* * Zero or more statements. Generate a list of pointers to * statement descriptors. */ (AgStack<Statement *>) statements -> =AgStack<Statement *>(); -> statements:s, statement:x =s.push(x); /* * A single statement. * * Here, an "open" statement is a statement that can legally be * followed by an "else" keyword. A "closed" statement is one that * cannot. * * This resolves the common if-then-else ambiguity. See ifelse.html for * a discussion of the ambiguity and this technique for resolving it. */ (Statement *) statement -> closed statement -> open statement /* Any statement than can accept a dengling else clause is an open statement */ (Statement *) open statement -> "if", '(', expression:x, ')', statement:s = PCB.ast->makeIfStatement(x, s); -> "if", '(', expression:x, ')', closed statement:s1, "else", open statement:s2 = PCB.ast->makeIfElseStatement(x,s1,s2); -> "while", '(', expression:x, ')', open statement:s = PCB.ast->makeWhileStatement(x,s); -> "for", '(', expression:init, ';', expression:cond, ';', expression:inc, ')', open statement:s = PCB.ast->makeForStatement(init, cond, inc, s); (Statement *) closed statement -> "if", '(', expression:x, ')', closed statement:s1, "else", closed statement:s2 = PCB.ast->makeIfElseStatement(x,s1,s2); -> "while", '(', expression:x, ')', closed statement:s = PCB.ast->makeWhileStatement(x,s); -> "for", '(', expression:init, ';', expression:cond, ';', expression:inc, ')', closed statement:s = PCB.ast->makeForStatement(init, cond, inc, s); -> simple statement:x = x; /* * Statements that do not end with other statements. These all behave the * same way with respect to the closed statement/open statement construct * above, and are therefore factored out to PCB.ast->make it clearer. * * The bare expression appendss a pop instruction so that the resulting * byte code will discard the expression's value. (This is not an * optimizing compiler.) */ (Statement *) simple statement -> "do", statement:s, "while", '(', expression:x, ')', ';' = PCB.ast->makeDoStatement(s,x); -> expression:x, ';' = PCB.ast->makeExpressionStatement(x); -> ';' = PCB.ast->makeStatement(); -> '{', statements:s, '}' = PCB.ast->makeStatementBlock(s); // General expression. As in C, comma expression has the lowest precedence. (Expression *) expression -> assignment expression -> expression:x, ',', assignment expression:y = PCB.ast->makeCommaExpression(x,y); /* * Next precedence: assignments. Again, as in C, except we don't * support quite all the operators. */ (Expression *) assignment expression -> conditional expression -> name:k, '=', assignment expression:x =PCB.ast->makeSimpleAssignment(k, x); -> name:k, "+=", assignment expression:x =PCB.ast->makeAddMemory(k, x); -> name:k, "-=", assignment expression:x =PCB.ast->makeSubMemory(k, x); -> name:k, "*=", assignment expression:x =PCB.ast->makeMulMemory(k, x); -> name:k, "/=", assignment expression:x =PCB.ast->makeDivMemory(k, x); // Conditional expression (ternary operator) (Expression *) conditional expression -> logical or expression -> logical or expression:c, '?', expression:x, ':', conditional expression:y =PCB.ast->makeConditionalExpression(c,x,y); // Logical expressions with short-cut evaluation, as in C. (Expression *) logical or expression -> logical and expression -> logical or expression:x, "||", logical and expression:y =PCB.ast->makeLogicalOrExpression(x, y); (Expression *) logical and expression -> equality expression -> logical and expression:x, "&&", equality expression:y =PCB.ast->makeLogicalAndExpression(x,y); // Arithmetic expressions, in operator precedence order. (Expression *) equality expression -> relational expression -> equality expression:x, "==", relational expression:y =PCB.ast->makeEqExpression(x,y); -> equality expression:x, "!=", relational expression:y =PCB.ast->makeNeExpression(x,y); (Expression *) relational expression -> additive expression -> relational expression:x, '<', additive expression:y =PCB.ast->makeLtExpression(x,y); -> relational expression:x, "<=", additive expression:y =PCB.ast->makeLeExpression(x,y); -> relational expression:x, '>', additive expression:y =PCB.ast->makeGtExpression(x,y); -> relational expression:x, ">=", additive expression:y =PCB.ast->makeGeExpression(x,y); (Expression *) additive expression -> multiplicative expression -> additive expression:x, '+', multiplicative expression:y =PCB.ast->makeAddExpression(x,y); -> additive expression:x, '-', multiplicative expression:y =PCB.ast->makeSubExpression(x,y); (Expression *) multiplicative expression -> unary expression -> multiplicative expression:x, '*', unary expression:y =PCB.ast->makeMulExpression(x,y); -> multiplicative expression:x, '/', unary expression:y =PCB.ast->makeDivExpression(x,y); (Expression *) unary expression -> factor -> '-', unary expression:x =PCB.ast->makeNegExpression(x); -> '+', unary expression:x =x; -> '!', unary expression:x =PCB.ast->makeNotExpression(x); /* * Syntactically, we can use ** for exponentiation because we don't have * pointers. (In C, ** could be confused with pointer indirection.) * Note that the precedence of ** is inserted between unary +/- and unary !. */ (Expression *) factor -> primary -> primary:x, "**", unary expression:y =PCB.ast->makePowExpression(x,y); /* * Primary expression - bottom level of expression syntax. * Variable references, constants, the builtin functions. * Also, another expression in parentheses. (This is how you make * parentheses work the way they're supposed to.) */ (Expression *) primary -> real:x =PCB.ast->makeConstant(x); -> name:k =PCB.ast->makeVariable(k); -> "log", '(', expression:x, ')' =PCB.ast->makeLogExpression(x); -> "exp", '(', expression:x, ')' =PCB.ast->makeExpExpression(x); -> "sqrt", '(', assignment expression:x, ')' =PCB.ast->makeSqrtExpression(x); -> '(', expression:x, ')' =x; // -- LEXICAL UNITS ------------------------------------------------ digit = '0-9' eof = 0 letter = 'a-z' + 'A-Z' + '_' (void) white space -> ' ' + '\t' + '\f' + '\v' + '\r' + '\n' -> "/*", ~eof?..., "*/" // C style comment -> "//", ~(eof+'\n')?..., '\n' // C++ style comment (double) real -> simple real:x =x; -> simple real:x, 'e'+'E', '+'?,exponent:e =x*pow(10,e); -> simple real:x, 'e'+'E', '-',exponent:e =x*pow(10,-e); (double) simple real -> integer part:i, '.', fraction part:f = i+f; -> integer part:i, '.'? = i; -> '.', fraction part:f = f; (double) integer part -> digit:d = d-'0'; -> integer part:x, digit:d = 10*x + d-'0'; (double) fraction part -> digit:d =(d-'0')/10.; -> digit:d, fraction part:f =(d-'0' + f)/10.; (int) exponent -> digit:d = d-'0'; -> exponent:x, digit:d = 10*x + d-'0'; (AgString) name -> letter: c =AgString().concat(c); -> name:s, letter+digit: c =s.concat(c); { // begin embedded C void ag_delete_wrappers(astParse_pcb_struct *); void parseStatements(AbstractSyntaxTree *tree, char *text) { astParse_pcb_struct pcb; pcb.ast = tree; pcb.pointer = (unsigned char *) text; astParse(&pcb); if (pcb.exit_flag == AG_SUCCESS_CODE) tree->setRoot(astParse_value(&pcb)); else ag_delete_wrappers(&pcb); } } // end of embedded C /********************* End of bciast.syn ************************/