tagged release 0.6.4
[parrot.git] / languages / tcl / src / grammar / expr / expression.pg
blob23a7aaacc83924e853cb2546c611effd5a69b61f
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.
8 token ws { \h* }
10 token program {
11    | <[;\n\r\t\ ]>* <command> [ <.ws> <[\r\n;]> <.ws> <command>? ]*
12    | $<empty>=[^\s*$]
15 token command {
16     | '#' \N*
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\ ]>+ )+
23           ]
24         ) \h*
25       ]+
28 token substitution {
29     | <command_substitution>
30     | <variable_substitution>
31     | <backslash_substitution>
34 token quoted_word {
35     '"' $<chunk>=( <substitution> | '$' | <-[[$\\"]>+ )* [ '"' | <error: 'missing "'> ]
38 token braced_word {
39     <PGE::Text::bracketed: {}>
40   | '{' <error: 'missing close-brace'>
43 token command_substitution {
44     '[' ']'
45   | '[' <[;\n\r\t\ ]>* <subcommand> [ <.ws> <[\r\n;]> <.ws> <subcommand>? ]* ']'
46   | '[' <error: 'missing close-bracket'>
49 token subcommand {
50     | '#' \N*
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\ ]>+ )+
57           ]
58         ) \h*
59       ]+
62 token variable_substitution {
63     '$' [ '{'  ( <-[}]>+ )  '}'
64         | ('::'?<.name>) [ '(' $<index>=( <substitution> | '$' | <-[[$\\)]>+ )+ ')' ]?
65         ]
68 token backslash_substitution {
69     \\ [ x <[0..9a..fA..F]>+
70        | u <[0..9a..fA..F]>**{1..4}
71        | <[0..7]>**{1..3}
72        | .
73        ]
76 token expand {
77     '{*}'<!before \s>
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> }
85 # Actual [expr] items
87 token term {
88       <substitution>
89     | <quoted_word>
90     | <braced_word>
91     | <number>
92     | <mathfunc>
93     | <nested>
94     | <boolean>
95     | <[a..zA..Z]> <syntax_error_variable_or_function>
98 ## used by term
100 rule boolean {
101     (:i true  | tru  | tr  | t
102       | false | fals | fal | fa | f
103       | yes   | ye   | y
104       | no    | n
105       | on
106       | off   | of )
107     <.wb>
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   |
131  srand  | tanh?  | wide
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.
139 token mathfunc {
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=') {...}