Mercurial > ~dholland > hg > ag > index.cgi
diff tests/agcl/oldagsrc/bciastp.syn @ 0:13d2b8934445
Import AnaGram (near-)release tree into Mercurial.
author | David A. Holland |
---|---|
date | Sat, 22 Dec 2007 17:52:45 -0500 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/agcl/oldagsrc/bciastp.syn Sat Dec 22 17:52:45 2007 -0500 @@ -0,0 +1,306 @@ +{ +/* + 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 ************************/