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
     ;

%%