#define DATA(x) struct x : Data< Node::x > {}; #define TOKEN(x) struct t##x : Token< Node::x > {}; DATA(Symbol); DATA(String); DATA(Integer); DATA(Real); TOKEN(Assign); TOKEN(Semicolon); TOKEN(Comma); TOKEN(Not); TOKEN(Index); TOKEN(Minus); TOKEN(Plus); TOKEN(Times); TOKEN(Divide); TOKEN(LeftBrace); TOKEN(RightBrace); TOKEN(LeftParen); TOKEN(RightParen); TOKEN(LeftBracket); TOKEN(RightBracket); TOKEN(Eof); TOKEN(Less); TOKEN(LessEqual); TOKEN(Equal); TOKEN(GreaterEqual); TOKEN(Greater); TOKEN(NotEqual); TOKEN(And); TOKEN(Or); struct Expr; struct List; struct ArgList; // Literal ::= | | | struct Literal : DataOr< Node::Symbol, Node::String, Node::Integer, Node::Real > {}; struct ParenExpr : TokenAndStore< tLeftParen, And< Expr, Expect< tRightParen > > > {}; // FunctionOrFunctionCall ::= [] + struct LookSymbolAndBracket : LookAhead< Token< Node::Symbol>, Token< Node::LeftBracket > >{}; struct LookBracketOnly : LookAhead< Token< Node::LeftBracket > > {}; struct LookFunctionOrFunctionCall : Or< LookSymbolAndBracket, LookBracketOnly >{}; struct FunctionOrFunctionCall : TokenAndStore< LookFunctionOrFunctionCall, Store< Node::Function, Opt< Data< Node::Symbol > >, Plus< ArgList > > >{}; // Operator precedence level 0 // ( Expr ) // FunctionOrFunctionCall // Literal // List struct Expr0 : Or< ParenExpr, FunctionOrFunctionCall, Literal, List > {}; // Operator precedence level 1: // Binary @ Index struct OpExpr1 : TokenAndStore< tIndex, Expr0 > {}; struct Expr1 : BinaryOperator< Node::Index, Expr0, OpExpr1 > {}; // Operator precedence level 2: // Unary + Plus // Unary - Minus // Unary ! Not struct Expr2; struct Expr2 : Or< TokenAndStore< tPlus, Expr2 >, TokenAndStore< tMinus, Store< Node::Minus, Expr2 > >, TokenAndStore< tNot, Store< Node::Not, Expr2 > >, Expr1 > {}; // Operator precedence level 3: // Binary * Times // Binary / Divide struct OpExpr3 : Or< TokenAndStore< tTimes, Expr2 >, TokenAndStore< tDivide, Store< Node::Divide, Expr2 > > > {}; struct Expr3 : BinaryOperator< Node::Times, Expr2, OpExpr3 > {}; // Operator precedence level 4: // Binary + Plus // Binary - Minus struct OpExpr4 : Or< TokenAndStore< tPlus, Expr3 >, TokenAndStore< tMinus, Store< Node::Minus, Expr3 > > > {}; struct Expr4 : BinaryOperator< Node::Plus, Expr3, OpExpr4 > {}; // Operator precedence level 5: // Binary < Less // Binary <= LessEqual // Binary = Equal // Binary >= GreaterEqual // Binary > Greater // Binary != NotEqual struct CmpOpData : DataOr< Node::Less, Node::LessEqual, Node::Equal, Node::GreaterEqual, Node::Greater, Node::NotEqual > {}; struct CmpOpToken : TokenOr< Node::Less, Node::LessEqual, Node::Equal, Node::GreaterEqual, Node::Greater, Node::NotEqual > {}; struct Expr5 : BinaryOperator< Node::Comparison, Expr4, TokenAndStore< LookAhead< CmpOpToken >, And< CmpOpData, Expr4 > > > {}; // Operator precedence level 6: // Binary & And struct Expr6 : BinaryOperator< Node::And, Expr5, TokenAndStore< tAnd, Expr5 > >{}; // Operator precedence level 7: // Binary | Or struct Expr7 : BinaryOperator< Node::Or, Expr6, TokenAndStore< tOr, Expr6 > >{}; // Operator precedence level 8: // Binary := Assign struct Expr8 : BinaryOperator< Node::Assign, Expr7, TokenAndStore< tAssign, Expr7 > >{}; struct Expr : Expr8 {}; struct ListBody : Opt< Expr, Star< tComma, Expr > > {}; struct List : TokenAndStore< tLeftBrace, Store< Node::List, ListBody, Expect< tRightBrace > > > {}; struct ArgList : TokenAndStore< tLeftBracket, Store< Node::ArgList, ListBody, Expect< tRightBracket > > > {}; // Stmt ::= struct Stmt : Store< Node::Statement, Expr, tSemicolon > {}; // Prgm ::= { } struct Prgm : Store< Node::Program, Star< Stmt >, tEof > {};