tagged release 0.7.1
[parrot.git] / languages / squaak / src / parser / grammar.pg
blob4cef7273a55181e5ab4f2a3187e00919575be66b
1 # Copyright (C) 2008, The Perl Foundation.
2 # $Id$
5 =begin overview
7 This is the grammar for Squaak written as a sequence of Perl 6 rules.
9 =end overview
11 grammar Squaak::Grammar is PCT::Grammar;
13 rule TOP {
14     {*}                                      #= open
15     <stat_or_def>*
16     [ $ || <.panic: 'Syntax error'> ]
17     {*}                                      #= close
20 rule stat_or_def {
21     | <statement> {*}                        #= statement
22     | <sub_definition> {*}                   #= sub_definition
25 rule statement {
26     | <if_statement> {*}                     #= if_statement
27     | <while_statement> {*}                  #= while_statement
28     | <for_statement> {*}                    #= for_statement
29     | <try_statement> {*}                    #= try_statement
30     | <throw_statement> {*}                  #= throw_statement
31     | <return_statement> {*}                 #= return_statement
32     | <sub_call> {*}                         #= sub_call
33     | <assignment> {*}                       #= assignment
34     | <variable_declaration> {*}             #= variable_declaration
35     | <do_block> {*}                         #= do_block
38 rule if_statement {
39     'if' <expression> 'then' <block> ['else' <else=block>]? 'end'
40     {*}
43 rule while_statement {
44     'while' <expression> 'do' <block> 'end'
45     {*}
48 rule for_statement {
49     'for' <for_init> ',' <expression> [',' <step=expression>]? 'do'
50     <statement>*
51     'end'
52     {*}
55 rule for_init {
56     'var' <identifier> '=' <expression>
57     {*}
60 rule try_statement {
61     'try' <try=block> 'catch' <exception> <catch=block> 'end'
62     {*}
65 rule exception {
66     <identifier>
67     {*}
70 rule throw_statement {
71     'throw' <expression>
72     {*}
75 rule return_statement {
76     'return' <expression>
77     {*}
80 rule block {
81     {*}                                #= open
82     <statement>*
83     {*}                                #= close
86 rule do_block {
87     'do' <block> 'end'
88     {*}
91 rule assignment {
92     <primary> '=' <expression>
93     {*}
96 rule sub_definition {
97     'sub' <identifier> <parameters>
98     <statement>*
99     'end'
100     {*}
103 rule parameters {
104     '(' [ <identifier> [',' <identifier>]* ]? ')'
105     {*}
108 rule variable_declaration {
109     'var' <identifier> ['=' <expression>]?
110     {*}
113 rule sub_call {
114     <primary> <arguments>
115     {*}
118 rule arguments {
119     '(' [ <expression> [',' <expression>]* ]? ')'
120     {*}
123 rule primary {
124     <identifier> <postfix_expression>*
125     {*}
128 rule postfix_expression {
129     | <key> {*}                      #= key
130     | <member> {*}                   #= member
131     | <index> {*}                    #= index
134 rule key {
135     '{' <expression> '}'
136     {*}
139 rule member {
140     '.' <identifier>
141     {*}
144 rule index {
145     '[' <expression> ']'
146     {*}
149 rule term {
150    | <float_constant> {*}            #= float_constant
151    | <integer_constant> {*}          #= integer_constant
152    | <string_constant> {*}           #= string_constant
153    | <hash_constructor> {*}          #= hash_constructor
154    | <array_constructor> {*}         #= array_constructor
155    | <sub_call> {*}                  #= sub_call
156    | <primary> {*}                   #= primary
157    | '(' <expression> ')' {*}        #= expression
160 rule hash_constructor {
161     '{' [ <named_field> [',' <named_field>]* ]? '}'
162     {*}
165 rule named_field {
166     <string_constant> '=>' <expression>
167     {*}
170 rule array_constructor {
171     '[' [ <expression> [',' <expression>]* ]? ']'
172     {*}
175 token identifier {
176     <!keyword> <ident>
177     {*}
180 token integer_constant {
181     \d+
182     {*}
185 token float_constant {
186     [
187     | \d+ '.' \d*
188     | \d* '.' \d+
189     ]
190     {*}
193 token string_constant {
194     \" <string_literal: '"'> \"
195     {*}
198 token keyword {
199     ['and'|'catch' |'do' |'else' |'end' |'for'|'if'   |'not'
200     |'or' |'return'|'sub'|'throw'|'try' |'var'|'while']>>
203 rule expression is optable { ... }
205 proto 'infix:or'       is precedence('1')     is pasttype('unless') { ... }
206 proto 'infix:and'      is tighter('infix:or') is pasttype('if')     { ... }
208 proto 'infix:<'        is tighter('infix:and')                      { ... }
209 proto 'infix:<='       is equiv('infix:<')                          { ... }
210 proto 'infix:>'        is equiv('infix:<')                          { ... }
211 proto 'infix:>='       is equiv('infix:<')                          { ... }
212 proto 'infix:=='       is equiv('infix:<')                          { ... }
213 proto 'infix:!='       is equiv('infix:<')                          { ... }
215 proto 'infix:+'        is tighter('infix:<')  is pirop('n_add')     { ... }
216 proto 'infix:-'        is equiv('infix:+')    is pirop('n_sub')     { ... }
218 proto 'infix:..'       is equiv('infix:+')    is pirop('n_concat')  { ... }
220 proto 'infix:*'        is tighter('infix:+')  is pirop('n_mul')     { ... }
221 proto 'infix:%'        is equiv('infix:*')    is pirop('n_mod')     { ... }
222 proto 'infix:/'        is equiv('infix:*')    is pirop('n_div')     { ... }
224 proto 'prefix:not'     is tighter('infix:*')    is pirop('n_not')   { ... }
225 proto 'prefix:-'       is tighter('prefix:not') is pirop('n_neg')   { ... }
227 proto 'term:'          is tighter('prefix:-')  is parsed(&term)      { ... }
230 ##  this <ws> rule treats # as "comment to eol"
231 ##  you may want to replace it with something appropriate
232 token ws {
233     <!ww>
234     [ '#' \N* \n? | \s+ ]*