tagged release 0.6.4
[parrot.git] / languages / punie / src / parser / grammar.pg
blobb4dd390a1c94326b89a8cec90547634876ca3ad6
1 # Copyright (C) 2005-2008, The Perl Foundation.
2 # $Id$
4 grammar Punie::Grammar is PCT::Grammar;
6 token TOP    {
7     <lineseq> [ $ || <panic: 'parse error'> ] {*}
10 token ws {
11     || \v+
12     || \h+
13     || '#' \N*
16 token block { \{ <lineseq> \} {*} }
19 rule compblock {
20     $<block>=<block>
21     ['elsif' \( <expr> \) <block> ]*
22     [['continue'|'else'] $<continue>=<block>]?
23     {*}
26 rule lineseq { <line>*  {*} }
28 token line {
29     | <loop> {*}                                   #= loop
30     | <label>
31       [ <cond> {*}                                 #= cond
32       | <decl> {*}                                 #= decl
33       | <sideff> ';' {*}                           #= sideff
34       | ';' {*}                                    #= label
35       ] \s*
38 rule sideff {
39     <expr> [$<modifier>=<condmod>|<loopmod>]? {*}
42 rule condmod { $<sym>=[if|unless] <expr> {*} }
44 rule loopmod { $<sym>=[while|until] <expr> {*} }
46 rule label { [<word>\:]? {*} }
48 token word { [\w|_][\w|\d|_]* }
50 rule decl {
51     | <subroutine> {*} #= subroutine
52     #| <format> {*}     #= format
55 rule subroutine { sub <word> <block> {*} }
57 rule cond {
58     $<sym>=[if|unless]
59     \( <expr> \) <block>
60     [ 'elsif' \( <expr> \) <block> ]*
61     [ 'else' $<else>=<block> ]?
62     {*}
65 rule loop {
66     <label>
67     [ <while_loop> {*}                          #= while_loop
68     | <until_loop> {*}                          #= until_loop
69     | <for_loop> {*}                            #= for_loop
70     | <compblock> {*}                           #= compblock
71     ]
74 rule while_loop {
75     while <while_cond> <compblock> {*}
78 rule while_cond {
79     | \( <texpr> \) {*}         #= texpr
80     | <block> {*}               #= block
83 rule until_loop {
84     until <until_cond> <compblock> {*}
87 rule until_cond {
88     | \( <expr> \) {*}          #= expr
89     | <block> {*}               #= block
92 rule for_loop {
93     for \( [$<init>=<sideff>]? ';' <texpr> ';' [$<step>=<sideff>]? \)
94     <block>
95     {*}
98 rule texpr { <expr>? {*}  }
100 rule expr {
101     | <gprint> {*}                               #= gprint
102     | <oexpr> {*}                                #= oexpr
105 rule gprint { $<op>=['print'|'printf'|'chown'|'system'|'unlink'|'exec'|'kill'] <expr> {*} }
107 rule 'oexpr' is optable { ... }
110 token term {
111     | <list> {*}                                 #= list
112     | \( <expr> \) {*}                           #= expr
113     | <number> {*}                               #= number
114     | <integer> {*}                              #= integer
115     | <stringdouble> {*}                         #= stringdouble
116     | <stringsingle> {*}                         #= stringsingle
117     | <stringbacktick> {*}                       #= stringbacktick
118     | do <.ws> <block> {*}                       #= block
119     | <opcall> {*}                               #= opcall
120     | <subcall> {*}                              #= subcall
121     | <do_chop> {*}                              #= do_chop
122     | <do_pop> {*}                               #= do_pop
123     | <do_push> {*}                              #= do_push
124     | <do_shift> {*}                             #= do_shift
125     | <func0> {*}                                #= func0
126     | <func1> {*}                                #= func1
127     | <func2> {*}                                #= func2
128     | <func3> {*}                                #= func3
129     | <stabfun> {*}                              #= stabfun
130     | <variable> {*}                             #= variable
131     | <do_split> {*}                             #= split
132     | <do_join> {*}                              #= join
135 rule func0 { <fun0> {*} }
137 token fun0 { 'fork'|'time'|'times' }
139 rule func1 { <fun1>  \( <expr> \) {*} }
141 token fun1 { 'exp'|'gmtime'|'hex'|'int'|'length'|'localtime'|'log'|'ord'|'oct'|'sqrt'|'umask' }
143 rule func2 { <fun2>  \( <oexpr> ',' <expr> \) {*} }
145 token fun2 { 'crypt'|'index'|'link'|'rename' }
147 rule func3 { <fun3>  \( <oexpr> ',' <oexpr> ',' <expr> \) {*} }
149 token fun3 { 'substr' }
151 rule stabfun { <sfun> \( <word> \) {*} }
153 token sfun { 'each'|'keys'|'values' }
155 rule list {
156     \( \)  {*}
159 ## XXX add "pattern" to lexical rules.
160 rule do_split {
161     'split' [\( <variable> [',' <variable> [',' <expr>]? ]? \)]?
164 ## XXX complete this and implement
165 rule do_join {
166     'join' [\( <oexpr> ',' <expr> \)]?
169 rule do_chop {
170     'chop' [\( <expr> \)]?   {*}
173 rule do_pop {
174     'pop'
175     [ <arrayarg>
176     | <wordarg>
177     ]
178     {*}
181 rule do_push {
182     $<op>=['push'|'unshift'] \( <arrayvar> ',' <expr> \)  {*}
185 rule do_shift {
186     'shift' [$<arg>=<arrayarg>|<wordarg>]?  {*}
189 rule wordarg { \( <word> \) | <word>  {*} }
191 rule arrayarg { \( <arrayvar> \) | <arrayvar>  {*}  }
193 rule variable {
194     | <sigil>? <word> <key>? {*}
195     | <special_variable> <key>? {*}
198 token arrayvar { '@' <word>  {*}  }
200 token special_variable { '$_' | '$#' | '$ ' '_' }
202 token sigil { '$#' | <[$@%]> {*} }
203 token key {
204     | $<KEY>=[\[] <.ws> <expr> <.ws> $<KEY_CLOSE>=[\]]
205     | $<KEY>=[\{] <.ws> <expr> <.ws> $<KEY_CLOSE>=[\}]
206     {*}
208 token integer { \d+ {*} }
209 token number { \d+\.\d+ {*} }
210 token stringdouble { '"' <string_literal: '"' > '"' {*} }
211 token stringsingle { \' <string_literal: '\'' > \' {*} }
212 token stringbacktick { \` <string_literal: '`'> \` {*} }
213 rule subcall { do $<sym>=<word> \( <expr>? \) {*} }
214 rule opcall  { $<sym>=<op> \( <expr>? \) {*} }
216 token op {
217     | open
218     | die
221 token ws {
222     [ \s+
223     | \# \N*
224     ]*
225     {*}
228 proto infix:<+> is assoc('left') is precedence('=')
229     is pirop('n_add')
230     {...}
232 proto infix:<-> is assoc('left') is equiv(infix:<+>)
233     is pirop('n_sub')
234     {...}
236 proto infix:<.> is assoc('left')  is equiv(infix:<+>)
237     is pirop('n_concat')
238     {...}
240 proto infix:<*> is assoc('left') is tighter(infix:<+>)
241     is pirop('n_mul')
242     {...}
244 proto infix:</> is assoc('left') is equiv(infix:<*>)
245     is pirop('n_div')
246     {...}
248 proto infix:<%> is assoc('left') is equiv(infix:<*>)
249     is pirop('n_mod')
250     {...}
252 proto infix:<x> is assoc('left') is equiv(infix:<*>)
253     {...}
255 proto prefix:<-> is tighter(infix:<*>) is assoc('right') { ... }
256 proto prefix:<~> is equiv(prefix:<->) is assoc('right') { ... }
257 proto prefix:<!> is equiv(prefix:<->) is assoc('right') { ... }
259 proto postfix:<++> is tighter(prefix:<->) is assoc('non') is lvalue(1) { ... }
260 proto postfix:<--> is equiv(postfix:<++>)is assoc('non') is lvalue(1) { ... }
261 proto prefix:<++> is equiv(postfix:<++>) is assoc('non') is lvalue(1) { ... }
262 proto prefix:<--> is equiv(postfix:<++>) is assoc('non') is lvalue(1) { ... }
265 proto infix:«<<» is looser(infix:<+>) is assoc('left')
266 #    is pirop('shl') # XXX pirop()s with non PREG destinations don't work yet
267     {...}
269 proto infix:«>>» is equiv(infix:«<<») is assoc('left')
270 #    is pirop('shr') # XXX pirop()s with non PREG destinations don't work yet
271     {...}
273 proto infix:«<»  is looser(infix:«<<») is assoc('non') {...}
274 proto infix:«>»  is equiv(infix:«<»)   is assoc('non') {...}
275 proto infix:«<=» is equiv(infix:«<»)   is assoc('non') {...}
276 proto infix:«>=» is equiv(infix:«<»)   is assoc('non') {...}
277 proto infix:<lt> is equiv(infix:«<»)   is assoc('non') {...}
278 proto infix:<gt> is equiv(infix:«<»)   is assoc('non') {...}
279 proto infix:<le> is equiv(infix:«<»)   is assoc('non') {...}
280 proto infix:<ge> is equiv(infix:«<»)   is assoc('non') {...}
282 proto infix:<==> is looser(infix:«<») is assoc('non') {...}
283 proto infix:<!=> is equiv(infix:<==>) is assoc('non') {...}
285 proto infix:<eq> is equiv(infix:<==>) is assoc('non')
286     {...}
287 proto infix:<ne> is equiv(infix:<==>) is assoc('non')
288     {...}
290 proto infix:<&> is looser(infix:<==>) is assoc('left')
291 #    is pirop('band') # XXX pirop()s with non PREG destinations don't work yet
292     {...}
294 proto infix:<|> is looser(infix:<&>) is assoc('left')
295 #    is pirop('bor') # XXX pirop()s with non PREG destinations don't work yet
296     {...}
298 proto infix:<^> is equiv(infix:<|>)   is assoc('left')
299 #    is pirop('bxor') # XXX pirop()s with non PREG destinations don't work yet
300     {...}
302 proto infix:<&&> is looser(infix:<|>)  is assoc('left')
303     is pasttype('if')
304     {...}
305 proto infix:<||> is looser(infix:<&&>) is assoc('left')
306     is pasttype('unless')
307     {...}
309 proto infix:<..> is looser(infix:<||>) is assoc('non')
310     {...}
312 proto ternary:<? :> is looser(infix:<..>) is assoc('right')
313     is pasttype('if')
314     {...}
316 proto infix:<=> is looser(ternary:<? :>)
317     is pirop('assign')
318     is lvalue(1)
319     {...}
321 proto infix:<,> is looser(infix:<=>) is assoc('list')
322     { ... }
324 proto term: is tighter(infix:<+>) is parsed(&term) { ... }