1 grammar TclExpr::Grammar;
3 # RT#40688: This began as an [expr] only grammar, and has since grown to
4 # encompass the language itself. Either rename the whole thing, or,
5 # preferentially, split out the non-expr specific bits into another
6 # grammar that this one can then refer to.
11 | <[;\n\r\t\ ]>* <command> [ <.ws> <[\r\n;]> <.ws> <command>? ]*
17 | [ $<word>=( <expand>?
18 [ <quoted_word> [ <before [<[;\n\r\t\ ]>|$]>
19 | <error: 'extra characters after close-quote'> ]
20 | <braced_word> [ <before [<[;\n\r\t\ ]>|$]>
21 | <error: 'extra characters after close-brace'> ]
22 | $<chunk>=( <substitution> | '$' | <-[[$\\;\n\r\t\ ]>+ )+
29 | <command_substitution>
30 | <variable_substitution>
31 | <backslash_substitution>
35 '"' $<chunk>=( <substitution> | '$' | <-[[$\\"]>+ )* [ '"' | <error: 'missing "'> ]
39 <PGE::Text::bracketed: {}>
40 | '{' <error: 'missing close-brace'>
43 token command_substitution {
45 | '[' <[;\n\r\t\ ]>* <subcommand> [ <.ws> <[\r\n;]> <.ws> <subcommand>? ]* ']'
46 | '[' <error: 'missing close-bracket'>
51 | [ $<word>=( <expand>?
52 [ <quoted_word> [ <before [<[\];\n\r\t\ ]>|$]>
53 | <error: 'extra characters after close-quote'> ]
54 | <braced_word> [ <before [<[\];\n\r\t\ ]>|$]>
55 | <error: 'extra characters after close-brace'> ]
56 | $<chunk>=( <substitution> | \$ | <-[[$\]\\;\n\r\t\ ]>+ )+
62 token variable_substitution {
63 '$' [ '{' ( <-[}]>+ ) '}'
64 | ('::'?<.name>) [ '(' $<index>=( <substitution> | '$' | <-[[$\\)]>+ )+ ')' ]?
68 token backslash_substitution {
69 \\ [ x <[0..9a..fA..F]>+
70 | u <[0..9a..fA..F]>**{1..4}
80 # this is so we can use these rules in [subst]
81 token subst_backslash { <backslash_substitution> }
82 token subst_command { <command_substitution> }
83 token subst_variable { <variable_substitution> }
95 | <[a..zA..Z]> <syntax_error_variable_or_function>
101 (:i true | tru | tr | t
102 | false | fals | fal | fa | f
110 rule nested { '(' <expression> ')' }
112 token number { <scientific> | <float> | <integer> }
114 token float { (<[+\-]>)? [ <[0..9]>+\.<[0..9]>* | \.<[0..9]>+ ] }
116 token scientific { (<float> | <integer>) <[Ee]> (<[+\-]>? <[0..9]>+) }
118 token decimal { [<[1..9]><[0..9]>*] | 0 }
120 token binary { 0<[bB]> ( <[01]>+ ) }
121 token octal { 0<[oO]>? ([ <[0..7]> | <[89]><[0..9]>* <invalid_octal> ]+) }
122 token raw_hex { <[0..9A..Fa..f]> + }
123 token hex { 0<[xX]> <raw_hex> }
124 token integer { (<[+\-]>)? [ <binary> | <hex> | <octal> | <decimal>] }
126 token nullary_function { rand }
128 token unary_function {
129 abs | acos | asin | atan | bool | ceil | cosh? | double |
130 entier | exp | floor | int | log[10]? | round | sinh? | sqrt |
134 token binary_function { atan2 | fmod | hypot | pow }
136 token nary_function { max | min }
138 # XXX This should actually be a PIR rule so we can add more rules.
140 [ <nary_function> | <binary_function> | <unary_function> | <nullary_function>
141 | ( <[a..zA..Z]>\w* ) '(' <unknown_math_function> ]
142 '(' [<expression> [',' <expression>]*]? ')'
145 rule 'expression' is optable {...}
147 proto 'term:' is precedence('16=')
148 is parsed(&term) {...}
150 proto 'prefix:-' is precedence('15=') {...}
151 proto 'prefix:+' is precedence('15=') {...}
152 proto 'prefix:~' is precedence('15=') {...}
153 proto 'prefix:!' is precedence('15=') {...}
155 proto 'infix:**' is precedence('14=') {...}
157 proto 'infix:*' is precedence('13=') {...}
158 proto 'infix:/' is precedence('13=') {...}
159 proto 'infix:%' is precedence('13=') {...}
161 proto 'infix:+' is precedence('12=') {...}
162 proto 'infix:-' is precedence('12=') {...}
164 proto 'infix:<<' is precedence('11=') {...}
165 proto 'infix:>>' is precedence('11=') {...}
167 proto 'infix:<' is precedence('10=') {...}
168 proto 'infix:>' is precedence('10=') {...}
169 proto 'infix:<=' is precedence('10=') {...}
170 proto 'infix:>=' is precedence('10=') {...}
172 proto 'infix:==' is precedence('09=') {...}
173 proto 'infix:!=' is precedence('09=') {...}
175 proto 'infix:eq' is precedence('08=') {...}
176 proto 'infix:ne' is precedence('08=') {...}
178 proto 'infix:in' is precedence('07=') {...}
179 proto 'infix:ni' is precedence('07=') {...}
181 proto 'infix:&' is precedence('06=') {...}
183 proto 'infix:^' is precedence('05=') {...}
185 proto 'infix:|' is precedence('04=') {...}
187 proto 'infix:&&' is precedence('03=') {...}
189 proto 'infix:||' is precedence('02=') {...}
191 proto 'ternary:? :' is precedence('01=') {...}