1 # Copyright (C) 2005-2008, The Perl Foundation.
4 grammar Punie::Grammar is PCT::Grammar;
7 <lineseq> [ $ || <panic: 'parse error'> ] {*}
16 token block { \{ <lineseq> \} {*} }
21 ['elsif' \( <expr> \) <block> ]*
22 [['continue'|'else'] $<continue>=<block>]?
26 rule lineseq { <line>* {*} }
33 | <sideff> ';' {*} #= 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|_]* }
51 | <subroutine> {*} #= subroutine
52 #| <format> {*} #= format
55 rule subroutine { sub <word> <block> {*} }
60 [ 'elsif' \( <expr> \) <block> ]*
61 [ 'else' $<else>=<block> ]?
67 [ <while_loop> {*} #= while_loop
68 | <until_loop> {*} #= until_loop
69 | <for_loop> {*} #= for_loop
70 | <compblock> {*} #= compblock
75 while <while_cond> <compblock> {*}
79 | \( <texpr> \) {*} #= texpr
80 | <block> {*} #= block
84 until <until_cond> <compblock> {*}
88 | \( <expr> \) {*} #= expr
89 | <block> {*} #= block
93 for \( [$<init>=<sideff>]? ';' <texpr> ';' [$<step>=<sideff>]? \)
98 rule texpr { <expr>? {*} }
101 | <gprint> {*} #= gprint
102 | <oexpr> {*} #= oexpr
105 rule gprint { $<op>=['print'|'printf'|'chown'|'system'|'unlink'|'exec'|'kill'] <expr> {*} }
107 rule 'oexpr' is optable { ... }
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' }
159 ## XXX add "pattern" to lexical rules.
161 'split' [\( <variable> [',' <variable> [',' <expr>]? ]? \)]?
164 ## XXX complete this and implement
166 'join' [\( <oexpr> ',' <expr> \)]?
170 'chop' [\( <expr> \)]? {*}
182 $<op>=['push'|'unshift'] \( <arrayvar> ',' <expr> \) {*}
186 'shift' [$<arg>=<arrayarg>|<wordarg>]? {*}
189 rule wordarg { \( <word> \) | <word> {*} }
191 rule arrayarg { \( <arrayvar> \) | <arrayvar> {*} }
194 | <sigil>? <word> <key>? {*}
195 | <special_variable> <key>? {*}
198 token arrayvar { '@' <word> {*} }
200 token special_variable { '$_' | '$#' | '$ ' '_' }
202 token sigil { '$#' | <[$@%]> {*} }
204 | $<KEY>=[\[] <.ws> <expr> <.ws> $<KEY_CLOSE>=[\]]
205 | $<KEY>=[\{] <.ws> <expr> <.ws> $<KEY_CLOSE>=[\}]
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>? \) {*} }
228 proto infix:<+> is assoc('left') is precedence('=')
232 proto infix:<-> is assoc('left') is equiv(infix:<+>)
236 proto infix:<.> is assoc('left') is equiv(infix:<+>)
240 proto infix:<*> is assoc('left') is tighter(infix:<+>)
244 proto infix:</> is assoc('left') is equiv(infix:<*>)
248 proto infix:<%> is assoc('left') is equiv(infix:<*>)
252 proto infix:<x> is assoc('left') is equiv(infix:<*>)
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
269 proto infix:«>>» is equiv(infix:«<<») is assoc('left')
270 # is pirop('shr') # XXX pirop()s with non PREG destinations don't work yet
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')
287 proto infix:<ne> is equiv(infix:<==>) is assoc('non')
290 proto infix:<&> is looser(infix:<==>) is assoc('left')
291 # is pirop('band') # XXX pirop()s with non PREG destinations don't work yet
294 proto infix:<|> is looser(infix:<&>) is assoc('left')
295 # is pirop('bor') # XXX pirop()s with non PREG destinations don't work yet
298 proto infix:<^> is equiv(infix:<|>) is assoc('left')
299 # is pirop('bxor') # XXX pirop()s with non PREG destinations don't work yet
302 proto infix:<&&> is looser(infix:<|>) is assoc('left')
305 proto infix:<||> is looser(infix:<&&>) is assoc('left')
306 is pasttype('unless')
309 proto infix:<..> is looser(infix:<||>) is assoc('non')
312 proto ternary:<? :> is looser(infix:<..>) is assoc('right')
316 proto infix:<=> is looser(ternary:<? :>)
321 proto infix:<,> is looser(infix:<=>) is assoc('list')
324 proto term: is tighter(infix:<+>) is parsed(&term) { ... }