hi,

attached a patch for languages/Pynie, adding:

* more grammar rules
* statement.t  for testing statements -- kinda simple, should be extended
* keyword rule, so that id's are not recognized as identifiers

regards,
kjs
Index: languages/pynie/src/parser/Grammar.pg
===================================================================
--- languages/pynie/src/parser/Grammar.pg	(revision 17174)
+++ languages/pynie/src/parser/Grammar.pg	(working copy)
@@ -37,6 +37,11 @@
 token compound_stmt {
     | <if_stmt>
     | <while_stmt>
+    | <for_stmt>
+    | <try_stmt>
+    | <with_stmt>
+    | <funcdef>
+    | <classdef>
 }
 
 rule if_stmt {
@@ -50,25 +55,174 @@
     [ <'else'> <':'> <suite> ]?
 }
 
+rule for_stmt {
+    <'for'> <target_list> <'in'> <expression_list> <':'> <suite>
+    [ <'else'> <':'> <suite> ]?
+}
+
+rule try_stmt {
+    <try1_stmt> | <try2_stmt>
+}
+
+rule try1_stmt {
+    <'try'> <':'> <suite>
+    [ <'except'> [ <expression> [ <','> <target> ]? ]? <':'> <suite> ]+
+    [ <'else'> <':'> <suite> ]?
+    [ <'finally'> <':'> <suite> ]?
+}
+
+rule try2_stmt {
+    <'try'> <':'> <suite>
+    <'finally'> <':'> <suite>
+}
+
+rule with_stmt {
+    <'with'> <expression> [ <'as'> <target> ]? <':'> <suite>
+}
+
+rule funcdef {
+    <decorators>? <'def'> <funcname> <'('> <parameter_list>? <')'>
+    [ <':'> | <?die: ':' expected> ] <suite>
+}
+
+
+rule decorators {
+    <decorator>+
+}
+
+rule decorator {
+    <'@'> <dotted_name> [ <'('> [ <argument_list> <','>? ]? <')'> ]? <?newline>
+}
+
+rule dotted_name {
+    <identifier> [ <'.'> <identifier> ]*
+}
+
+rule funcname {
+    <identifier>
+}
+
+rule parameter_list {
+    [ <defparameter> <','> ]*
+    [
+      <'*'> <identifier> [ <','> <'**'> <identifier> ]?
+    | <'**'> <identifier>
+    | <defparameter> <','>?
+    ]
+}
+
+rule defparameter {
+    <parameter> [ <'='> <expression> ]?
+}
+
+rule sublist {
+    <parameter> [ <','> <parameter> ]* <','>?
+}
+
+rule parameter {
+    <identifier> | <'('> <sublist> <')'>
+}
+
+
+rule classdef {
+    <'class'> <classname> <inheritance>? <':'> <suite>
+}
+
+rule classname {
+    <identifier>
+}
+
+rule inheritance {
+    <'('> <expression_list> <')'>
+}
+
 token simple_stmt {
+    | <assert_stmt>
+    | <assignment_stmt>
+    | <augmented_assignment_stmt>
+    | <pass_stmt>
+    | <del_stmt>
     | <print_stmt>
-    | <assignment_stmt>
+    | <return_stmt>
+    | <yield_stmt>
+    | <raise_stmt>
+    | <break_stmt>
+    | <continue_stmt>
+    | <import_stmt>
+    | <global_stmt>
     | <expression>
 }
 
+rule assert_stmt {
+    <'assert'> <expression> [ <','> <expression> ]?
+}
+
 rule assignment_stmt { [ <target_list> <'='> ]+ <expression_list> }
 
+rule augmented_assignment_stmt { <target> <augop> <expression_list> }
+
 rule target_list { <target> [ <','> <target> ]* (<','>)? }
 
 token target { <identifier> }
 
-token identifier { [ <?alpha> | <'_'> ] \w* }
+token identifier { <!reserved> [ <?alpha> | <'_'> ] \w* }
 
+token name { <!reserved> <[a..z]> [ <alpha> | <'_'> ]* }
+
 rule print_stmt {
     <'print'> [ <expression> [ <','> <expression> ]* (<','>?) ]?
 }
 
+rule pass_stmt {
+    <'pass'>
+}
 
+rule del_stmt {
+    <'del'> <target_list>
+}
+
+rule return_stmt {
+    <'return'> <expression_list>?
+}
+
+rule yield_stmt {
+    <'yield'> <expression_list>
+}
+
+rule break_stmt {
+    <'break'>
+}
+
+rule continue_stmt {
+    <'continue'>
+}
+
+rule raise_stmt {
+    <'raise'> [ <expression> [ <','> <expression> [ <','> <expression> ]? ]? ]?
+}
+
+rule global_stmt {
+    <'global'> <identifier> [ <','> <identifier> ]*
+}
+
+rule import_stmt {
+    | <'import'> <module> <import_alias>?
+      [ <','> <module> <import_alias>? ]*
+    | <'from'> <module> <'import'> <identifier> <import_alias>?
+      [ <','> <identifier> <import_alias>? ]*
+    | <'from'> <module> <'import'> <'('> <identifier> <import_alias>?
+      [ <','> <identifier> <import_alias>? ]* <','>? <')'>
+    | <'from'> <module> <'import'> <'*'>
+}
+
+rule import_alias {
+    <'as'> <name>
+}
+
+rule module {
+    [ <identifier> <'.'> ]* <identifier>
+}
+
 token literal {
     | <stringliteral>
     | <integer>
@@ -93,6 +247,9 @@
 
 rule listmaker { <expression> [ <','> <expression> ]* (<','>)? }
 
+token augop {
+    <'+='> | <'-='> | <'*='> | <'/='> | <'\%='> | <'**='>
+}
 
 ##  This identifies operators for the bottom-up parser
 
@@ -137,4 +294,19 @@
 proto 'infix:<'    is equiv('infix:==')  { ... }
 proto 'infix:>'    is equiv('infix:==')  { ... }
 
+
+## Python reserved words and keywords
+
+token reserved {
+    <keyword> | <'None'>
+}
+
+token keyword {
+    [ <'and'>   | <'assert'> | <'break'>  | <'class'>  | <'continue'> | <'def'>
+    | <'del'>   | <'elif'>   | <'else'>   | <'except'> | <'exec'>     | <'finally'>
+    | <'for'>   | <'from'>   | <'global'> | <'if'>     | <'import'>   | <'in'>
+    | <'is'>    | <'lambda'> | <'not'>    | <'or'>     | <'pass'>     | <'print'>
+    | <'raise'> | <'return'> | <'try'>    | <'while'>  | <'with'>     | <'yield'> ] \b
+}
+
 ## vim: expandtab sw=4
Index: languages/pynie/src/PAST/Grammar.tg
===================================================================
--- languages/pynie/src/PAST/Grammar.tg	(revision 17174)
+++ languages/pynie/src/PAST/Grammar.tg	(working copy)
@@ -28,12 +28,33 @@
 
   compound_stmt:
     $P0 = node['compound_stmt']
+  if_stmt:
     $P1 = $P0['if_stmt']
     if null $P1 goto while_stmt
     .return tree.'get'('past', $P1, 'Pynie::Grammar::if_stmt')
   while_stmt:
     $P1 = $P0['while_stmt']
+    if null $P1 goto for_stmt
     .return tree.'get'('past', $P1, 'Pynie::Grammar::while_stmt')
+  for_stmt:
+    $P1 = $P0['for_stmt']
+    if null $P1 goto try_stmt
+    .return tree.'get'('past', $P1, 'Pynie::Grammar::for_stmt')
+  try_stmt:
+    $P1 = $P0['try_stmt']
+    if null $P1 goto with_stmt
+    .return tree.'get'('past', $P1, 'Pynie::Grammar::try_stmt')
+  with_stmt:
+    $P1 = $P0['with_stmt']
+    if null $P1 goto funcdef
+    .return tree.'get'('past', $P1, 'Pynie::Grammar::with_stmt')
+  funcdef:
+    $P1 = $P0['funcdef']
+    if null $P1 goto classdef
+    .return tree.'get'('past', $P1, 'Pynie::Grammar::funcdef')
+  classdef:
+    $P1 = $P0['classdef']
+    .return tree.'get'('past', $P1, 'Pynie::Grammar::classdef')
 }
 
 
@@ -68,7 +89,98 @@
     .return tree.'get'('past', cnode, key)
 }
 
+transform past (Pynie::Grammar::assert_stmt) :language('PIR') {
+    .local pmc past
+    past = new 'PAST::Op'
 
+## From http://docs.python.org/ref/assert.html
+##    The simple form, "assert expression", is equivalent to
+##
+##if __debug__:
+##   if not expression: raise AssertionError
+##
+##The extended form, "assert expression1, expression2", is equivalent to
+##
+##if __debug__:
+##   if not expression1: raise AssertionError, expression2
+##
+    #past.'init'('node'=>node, 'pasttype'=>'if')
+    #$P0 = node['expression']
+
+
+    past.'init'('node'=>node, 'pasttype'=>'inline', 'inline'=>'# assert_stmt not implemented')
+    .return (past)
+
+}
+
+transform past (Pynie::Grammar::augmented_assignment_stmt) :language('PIR') {
+    .local pmc past
+    past = new 'PAST::Op'
+    past.'init'('node'=>node, 'pasttype'=>'inline', 'inline'=>'# augmented assignment stmt not implemented')
+    .return (past)
+}
+
+transform past (Pynie::Grammar::del_stmt) :language('PIR') {
+    .local pmc past
+    past = new 'PAST::Op'
+    past.'init'('node'=>node, 'pasttype'=>'inline', 'inline'=>'# del stmt not implemented')
+    .return (past)
+}
+
+# Handle "pass" statement; only emit a comment
+# Alternative would be to _not_ create a PAST node, but then
+# extra logic would be necessary in both stmt_list() and simple_stmt().
+#
+transform past (Pynie::Grammar::pass_stmt) :language('PIR') {
+    .local pmc past
+    past = new 'PAST::Op'
+    past.'init'('node'=>node, 'pasttype'=>'inline', 'inline'=>'# pass')
+    .return (past)
+}
+
+transform past (Pynie::Grammar::return_stmt) :language('PIR') {
+    .local pmc past
+    past = new 'PAST::Op'
+    past.'init'('node'=>node, 'pasttype'=>'pirop', 'pirop'=>'return')
+    $P0 = node['expression_list']
+
+## FIX:
+## Returning something does not work; 'method 'from' not found...
+    if null $P0 goto skip_expression_list
+    .local pmc expr_list_past
+    expr_list_past = tree.'get'('past', $P0, 'Pynie::Grammar::expression_list')
+    past.'push'(expr_list_past)
+  skip_expression_list:
+    .return (past)
+}
+
+## FIX:
+## generated code is nonsense for yield_stmt
+transform past (Pynie::Grammar::yield_stmt) :language('PIR') {
+    .local pmc past
+    past = new 'PAST::Op'
+    past.'init'('node'=>node, 'pasttype'=>'pirop', 'pirop'=>'yield')
+    $P0 = node['expression_list']
+    .local pmc expr_list_past
+    expr_list_past = tree.'get'('past', $P0, 'Pynie::Grammar::expression_list')
+    past.'push'(expr_list_past)
+    .return (past)
+}
+
+transform past (Pynie::Grammar::break_stmt) :language('PIR') {
+    .local pmc past
+    past = new 'PAST::Op'
+    past.'init'('node'=>node, 'pasttype'=>'inline', 'inline'=>'# break not implemented')
+    .return (past)
+}
+
+transform past (Pynie::Grammar::continue_stmt) :language('PIR') {
+    .local pmc past
+    past = new 'PAST::Op'
+    past.'init'('node'=>node, 'pasttype'=>'inline', 'inline'=>'# continue not implemented')
+    .return (past)
+}
+
 transform past (Pynie::Grammar::print_stmt) :language('PIR') {
     .local pmc past
     past = new 'PAST::Op'
@@ -94,7 +206,29 @@
     .return (past)
 }
 
+transform past (Pynie::Grammar::import_stmt) :language('PIR') {
+    .local pmc past
+    past = new 'PAST::Op'
+    past.'init'('node'=>node, 'pasttype'=>'inline', 'inline'=>'# import stmt not implemented')
+    .return (past)
+}
 
+transform past (Pynie::Grammar::raise_stmt) :language('PIR') {
+    .local pmc past
+    past = new 'PAST::Op'
+    past.'init'('node'=>node, 'pasttype'=>'inline', 'inline'=>'# raise stmt not implemented')
+    .return (past)
+}
+
+transform past (Pynie::Grammar::global_stmt) :language('PIR') {
+    .local pmc past
+    past = new 'PAST::Op'
+    past.'init'('node'=>node, 'pasttype'=>'inline', 'inline'=>'# global stmt not implemented')
+    .return (past)
+}
+
+
+
 transform past (Pynie::Grammar::expression) :language('PIR') {
     $P0 = node['expr']
     .return tree.'get'('past', $P0, 'Pynie::Grammar::expr')
@@ -297,23 +431,170 @@
 
 
 transform past (Pynie::Grammar::while_stmt) :language('PIR') {
-    .local pmc exprnode, stmtnode
-    exprnode = node['expression']
-    stmtnode = node['suite']
-    stmtnode = stmtnode[0]
+    .local pmc past
+    past = new 'PAST::Op'
+    past.'init'('node'=>node, 'pasttype'=>'inline', 'inline'=>'# while stmt not implemented')
+    .return (past)
 
-    .local pmc past, exprpast, stmtpast
+  #  .local pmc exprnode, stmtnode
+  #  exprnode = node['expression']
+  #  stmtnode = node['suite']
+  #  stmtnode = stmtnode[0]
+  #
+  #  .local pmc past, exprpast, stmtpast
+  #  past = new 'PAST::Op'
+  #  past.'init'('node'=>node, 'pasttype'=>'while')
+  #  exprpast = tree.'get'('past', exprnode, 'Pynie::Grammar::expression')
+  #  past.'push'(exprpast)
+  #  stmtpast = tree.'get'('past', stmtnode, 'Pynie::Grammar::suite')
+  #  past.'push'(stmtpast)
+  #  .return (past)
+}
+
+## FIX: complete this
+transform past (Pynie::Grammar::for_stmt) :language('PIR') {
+
+    .local pmc past
     past = new 'PAST::Op'
-    past.'init'('node'=>node, 'pasttype'=>'while')
-    exprpast = tree.'get'('past', exprnode, 'Pynie::Grammar::expression')
-    past.'push'(exprpast)
-    stmtpast = tree.'get'('past', stmtnode, 'Pynie::Grammar::suite')
-    past.'push'(stmtpast)
+    past.'init'('node'=>node, 'pasttype'=>'inline', 'inline'=>'# for stmt not implemented')
     .return (past)
+
+#   .local pmc tlistnode, elistnode, suitenode
+#   tlistnode = node['target_list']
+#   elistnode = node['expression_list']
+#   suitenode = node['suite']
+#
+#   .local pmc past, tlistpast, elistpast, suitepast
+#   past = new 'PAST::Op'
+#   past.'init'('node'=>node, 'pasttype'=>'while')
+#
+#   tlistpast = tree.'get'('past', tlistnode, 'Pynie::Grammar::target_list')
+#   #past.'push'(tlistpast)
+#
+#   elistpast = tree.'get'('past', elistnode, 'Pynie::Grammar::expression_list')
+#   past.'push'(elistpast)
+#
+#   suitepast = tree.'get'('past', suitenode, 'Pynie::Grammar::suite')
+#   past.'push'(suitepast)
+#
+#   .return (past)
 }
 
+transform past (Pynie::Grammar::try_stmt) :language('PIR') {
+    .local pmc past
+    past = new 'PAST::Op'
+    past.'init'('node'=>node, 'pasttype'=>'inline', 'inline'=>'# try stmt not implemented')
+    .return (past)
+}
 
+transform past (Pynie::Grammar::with_stmt) :language('PIR') {
+    .local pmc past
+    past = new 'PAST::Op'
+    past.'init'('node'=>node, 'pasttype'=>'inline', 'inline'=>'# with stmt not implemented')
+    .return (past)
+}
 
+transform past (Pynie::Grammar::funcdef) :language('PIR') {
+
+    .local pmc past
+    past = new 'PAST::Block'
+
+    .local pmc decnode, fnamenode, plistnode, suitenode
+#   decnode   = node['decorators']
+    fnamenode = node['funcname']
+#   plistnode = node['parameter_list']
+#   suitenode = node['suite']
+#
+#   .local pmc past
+#   past = new 'PAST::Block'
+#
+#   if null decnode goto skip_decorators
+#   # handle decorators
+#   printerr "Function decorators not implemented!\n"
+#   exit 1
+#
+# skip_decorators:
+    .local pmc fnamepast
+    fnamepast = tree.'get'('past', fnamenode, 'Pynie::Grammar::funcname')
+#
+#   if null plistnode goto skip_parameter_list
+#   #.local plistpast
+#   #plistpast = tree.'get'('past', plistnode, 'Pynie::Grammar::parameter_list')
+#   printerr "Parameters not implemented!\n"
+#   exit 1
+#
+# skip_parameter_list:
+#   .local pmc stmtpast
+#   stmtpast = tree.'get'('past', suitenode, 'Pynie::Grammar::suite')
+#
+#   # FIX
+#   past.'init'('node'=>node, 'name'=>fnamepast)
+#   .local pmc past
+#
+    past.'init'('node'=>node, 'name'=>fnamepast)
+    .return (past)
+}
+
+transform past (Pynie::Grammar::funcname) :language('PIR') {
+    $P0 = node['identifier']
+    .return tree.'get'('past', $P0, 'Pynie::Grammar::identifier')
+}
+
+
+## FIX: fix this, not sure about how to handle instructions such
+## as subclass etc.
+##
+transform past (Pynie::Grammar::classdef) :language('PIR') {
+
+    .local pmc past
+    past = new 'PAST::Op'
+    past.'init'('node'=>node, 'pasttype'=>'inline', 'inline'=>'# classdef stmt not implemented')
+    .return (past)
+
+#   .local pmc past
+#   past = new 'PAST::Stmts'
+#   past.'init'('node'=>node)
+#
+#   .local pmc instr
+#   instr = new 'PAST::Op'
+#
+#   $P0 = node['inheritance']
+#   if null $P0 goto skip_inheritance
+#   instr.'init'('node'=>node, 'pasttype'=>'pirop', 'pirop'=>'subclass')
+#   # inheritancenot implemented right now
+#   goto handle_class_body
+#
+# skip_inheritance:
+#   instr.'init'('node'=>node, 'pasttype'=>'pirop', 'pirop'=>'newclass')
+#   $P0 = node['classname']
+#   $P1 = tree.'get'('past', $P0, 'Pynie::Grammar::classname')
+#   instr.'push'($P1)
+#
+# handle_class_body:
+#   # add newclass or subclass instruction to Stmts node
+#   past.'push'(instr)
+#
+#   # add a .namespace[ <class_id> ] instruction to add methods?
+#   $P0 = node['suite']
+#   $P1 = tree.'get'('past', $P0, 'Pynie::Grammar::suite')
+#   past.'push'($P1)
+#
+#
+# done:
+#   .return (past)
+}
+
+## FIX: Return class name as a string, not using "get_global" as in identifier.
+transform past (Pynie::Grammar::classname) :language('PIR') {
+    $P0 = node['identifier']
+    .return tree.'get'('past', $P0, 'Pynie::Grammar::identifier')
+}
+
+transform past (Pynie::Grammar::inheritance) :language('PIR') {
+    $P0 = node['expression_list']
+    .return tree.'get'('past', $P0, 'Pynie::Grammar::expression_list')
+}
+
 transform past (Pynie::Grammar::suite) :language('PIR') {
     $P0 = node['stmt_list']
     if null $P0 goto statements
Index: languages/pynie/t/00-parrot/03-statement.t
===================================================================
--- languages/pynie/t/00-parrot/03-statement.t	(revision 0)
+++ languages/pynie/t/00-parrot/03-statement.t	(revision 0)
@@ -0,0 +1,68 @@
+
+print '1..12'
+
+while 1:
+  pass
+
+print 'ok 1\n'
+
+for x in 1:
+  pass
+
+print 'ok 2\n'
+
+class X:
+  pass
+
+print 'ok 3\n'
+
+
+def foo ( ) :
+  pass
+
+
+print 'ok 4\n'
+
+
+with x as y:
+  pass
+
+print 'ok 5\n'
+
+del a, b, c
+
+print 'ok 6\n'
+
+raise 1
+
+print 'ok 7\n'
+
+break
+
+print 'ok 8\n'
+
+continue
+
+print 'ok 9\n'
+
+global X, Y, Z
+
+print 'ok 10\n'
+
+import t as x
+
+print 'ok 11\n'
+
+from x import y
+
+import f
+
+from e import d
+
+from e import x as f
+
+from e import (a, b, c)
+
+from r import *
+
+print 'ok 12\n'

Reply via email to