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 ************************/