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
;
%%