Posted to tcl by kbk at Tue May 27 17:47:43 GMT 2008view pretty
/* * Let the terminal symbols of the grammar include the various operators that * can appear in expressions. UMINUS and UPLUS are fictitious operators * that are used to establish precedence for unary '-' and '+' */ %left ';' %right '=' %nonassoc '?' ':' %left OROR %left ANDAND %left '|' %left '^' %left '&' %nonassoc IN NI %nonassoc EQ NE %nonassoc EQUALS NOTEQUALS %left LSHIFT RSHIFT %left '-' '+' %left '*' '/' '%' %right EXPONENT %left '~' '!' UMINUS UPLUS /* * The terminal symbols also include: * NUMBER - Any string recognizable as an integer or floating-point * constant. * BOOLEAN_CONSTANT - One of the barewords that can be a boolean constant * BAREWORD - A bare word that is neither a Boolean constant nor an * operator. Note that a bare word may contain any number * of :: separators for namespaces. * DOUBLE_QUOTED_STRING - A string enclosed in double quotes * BRACED_STRING - A string enclosed in braces * BRACKETED_TCL_COMMAND - A Tcl command enclosed in brackets * VARIABLE_REF - A dollar sign '$', followed by a variable name * and an optional subscript, exactly as recognized * for substitution in today's [expr] parser. * WORDSUBSCRIPTEQUALS - (Let the lexer help the parser!) - A * bareword, followed by a string in parentheses, followed * by an equal sign. This lexeme represents a subscripted * variable reference on the left hand side of an equal sign. */ %nonassoc NUMBER BOOLEAN_CONSTANT BAREWORD DOUBLE_QUOTED_STRING BRACED_STRING BRACKETED_TCL_COMMAND VARIABLE_REF WORDSUBSCRIPTEQUALS /* * Finally, parentheses not appearing as part of subscripts are * terminal symbols. */ %nonassoc '(' ')' %% start : sequence; /* * The argument to an [expr] comprises one or more expressions, * separated with semicolons. (NOT newlines - that's incompatible with * todays [expr] command.) */ sequence : assignment_expr | sequence ';' assignment_expr ; /* * Expressions may contain assignments; the left hand sides of assignments * may be any bareword (including operators and Boolean constants), plus * a bareword with a subscript, a double-quoted string, or a braced string. */ assignment_expr : ternary_expr | word '=' assignment_expr | WORDSUBSCRIPTEQUALS assignment_expr | DOUBLE_QUOTED_STRING '=' assignment_expr | BRACED_STRING '=' assignment_expr ; /* * An expression may contain the ternary ? : operator */ ternary_expr : binary_expr | binary_expr '?' assignment_expr ':' assignment_expr ; /* * An expression may contain any of the usual binary operators. * Precedence and associativity are given in the table above. */ binary_expr : unary_expr | binary_expr OROR binary_expr | binary_expr ANDAND binary_expr | binary_expr '|' binary_expr | binary_expr '^' binary_expr | binary_expr '&' binary_expr | binary_expr IN binary_expr | binary_expr NI binary_expr | binary_expr EQ binary_expr | binary_expr NE binary_expr | binary_expr EQUALS binary_expr | binary_expr NOTEQUALS binary_expr | binary_expr LSHIFT binary_expr | binary_expr RSHIFT binary_expr | binary_expr '+' binary_expr | binary_expr '-' binary_expr | binary_expr '*' binary_expr | binary_expr '/' binary_expr | binary_expr '%' binary_expr | binary_expr EXPONENT binary_expr ; /* * An expression may contain any of the unary operators */ unary_expr : primary_expr | '-' unary_expr %prec UMINUS | '+' unary_expr %prec UPLUS | '~' unary_expr | '!' unary_expr ; /* * Primary symbols of an expression include: * $-substituted variable references * Function calls * Barewords * Numbers * Double quoted strings * Braced strings * Bracket-substituted commands * Parenthesized expressions */ primary_expr : VARIABLE_REF | word '(' expr_list ')' | word | NUMBER | DOUBLE_QUOTED_STRING | BRACED_STRING | BRACKETED_TCL_COMMAND | '(' assignment_expr ')' ; /* * An expression list for a function call comprises zero or more * expressions, separated by commas. */ expr_list : | nonempty_expr_list ; nonempty_expr_list : assignment_expr | nonempty_expr_list ',' assignment_expr ; /* * Barewords include bare words otherwise unrecognized, plus the operators * that are sequences of letters, plus the Boolean constants. */ word : BAREWORD | BOOLEAN_CONSTANT | IN %prec BAREWORD | NI %prec BAREWORD | EQ %prec BAREWORD | NE %prec BAREWORD ; %%