Author: pmichaud
Date: Thu Feb  9 23:09:08 2006
New Revision: 11495

Modified:
   trunk/compilers/pge/PGE/OPTable.pir
   trunk/compilers/pge/PGE/P6Rule.pir
   trunk/lib/Parrot/Test/PGE.pm
   trunk/t/compilers/pge/p6rules/builtins.t
   trunk/t/compilers/pge/p6rules/cclass.t
   trunk/t/compilers/pge/p6rules/metachars.t
Log:
* Improved parse error handling in operator precedence parser
* Updated Test/PGE.pm to report invalid rules


Modified: trunk/compilers/pge/PGE/OPTable.pir
==============================================================================
--- trunk/compilers/pge/PGE/OPTable.pir (original)
+++ trunk/compilers/pge/PGE/OPTable.pir Thu Feb  9 23:09:08 2006
@@ -286,6 +286,7 @@ representing the result of the parse.
     unless tok goto expect_term_empty
     bsr tok_match
     if oper goto found_term
+    if key == "" goto null_term
   expect_term_empty:
     unless termempty goto null_term
     tok = termempty
@@ -294,14 +295,19 @@ representing the result of the parse.
     bsr tok_match
     if oper goto found_term
   null_term:
-    unless tokstack goto term_error
+    unless tokstack goto missing_term
     top = tokstack[-1]
     $S0 = top["opts"]
     $I0 = index $S0, "nullterm"
-    if $I0 < 0 goto term_error
-    oper = newfrom(mob, wspos, "PGE::Match")
+    if $I0 < 0 goto missing_term
+    (oper, $S0, $P0, $P1) = newfrom(mob, wspos, "PGE::Match")
+    $P1 = wspos
     push termstack, oper
     goto expect_oper
+  missing_term:
+    $P0 = newfrom(mob, wspos, "PGE::Match")
+    push termstack, $P0
+    goto end
   found_term:
     tokcat = tok["syncat"]
     pos = oper.to()
@@ -380,13 +386,19 @@ representing the result of the parse.
     arity = $P0["arity"]
     $P0 = pop operstack
   reduce_args:
-    if arity < 1 goto reduce_end
-    dec arity
+    if arity < 1 goto reduce_saveterm
     $P1 = pop termstack
+    unless $P1 goto reduce_backtrack
+    dec arity
     $P0[arity] = $P1
     goto reduce_args
-  reduce_end:
+  reduce_backtrack:
+    pos = $P0.from()
+    if arity > 1 goto reduce_end
+    $P0 = $P1
+  reduce_saveterm:
     push termstack, $P0
+  reduce_end:
     ret
 
   tok_match:
@@ -413,20 +425,15 @@ representing the result of the parse.
     bsr reduce
     goto end
   end_1:
+    $I0 = elements termstack
+    if $I0 < 1 goto end_2
     $P0 = pop termstack
+    unless $P0 goto end_2
     mob["expr"] = $P0
     mpos = pos
     .return (mob)
-
-  term_error:
-    $P0 = new .Exception
-    $S0 = "Missing term at offset "
-    $S1 = wspos
-    $S0 .= $S1
-    $S0 .= "\n"
-    $P0["_message"] = $S0
-    throw $P0
-    mpos = -1
+  end_2:
+    mpos = -1 
     .return (mob)
 
   ternary_error:

Modified: trunk/compilers/pge/PGE/P6Rule.pir
==============================================================================
--- trunk/compilers/pge/PGE/P6Rule.pir  (original)
+++ trunk/compilers/pge/PGE/P6Rule.pir  Thu Feb  9 23:09:08 2006
@@ -610,6 +610,8 @@
     .local pmc sub
     .local pmc pad
 
+    null code
+    null sub
     if has_name goto p6rule_1
     name = "_pge_rule"
     if has_gram goto p6rule_1
@@ -621,6 +623,9 @@
 
     $P0 = find_global "PGE::Rule", "p6rule"
     exp = $P0(exp)
+    unless exp goto end
+    $S0 = exp
+    if $S0 != pattern goto end
     pad = new .Hash
     $P0 = new .Hash
     pad["reps"] = $P0
@@ -630,6 +635,7 @@
     $P0 = exp["expr"]
     $P0 = $P0.p6analyze(pad)
     exp["expr"] = $P0
+    if_null $P0, end
 
     $P0 = new .String
     $P0 = "\n.namespace [ \""

Modified: trunk/lib/Parrot/Test/PGE.pm
==============================================================================
--- trunk/lib/Parrot/Test/PGE.pm        (original)
+++ trunk/lib/Parrot/Test/PGE.pm        Thu Feb  9 23:09:08 2006
@@ -201,15 +201,19 @@ sub _generate_pir_for {
             target = $unicode"$target"
             pattern = "$pattern"
             (rulesub, code, exp) = p6rule_compile(pattern)
+            if_null rulesub, rule_fail
             match = rulesub(target)
             unless match goto match_fail
           match_success:
             print "matched"
             $captures
-            goto match_end
+            goto end
           match_fail:
             print "failed"
-          match_end:
+            goto end
+          rule_fail:
+            print "rule error"
+          end:
         .end\n);
 }
 

Modified: trunk/t/compilers/pge/p6rules/builtins.t
==============================================================================
--- trunk/t/compilers/pge/p6rules/builtins.t    (original)
+++ trunk/t/compilers/pge/p6rules/builtins.t    Thu Feb  9 23:09:08 2006
@@ -188,7 +188,7 @@ p6rule_is  ('az', '<+alpha>+', 'metasynt
 
 
 ## null pattern is illegal
-p6rule_like($str, '', '/Missing term at offset.*/',
+p6rule_like($str, '', '/rule error/',
     'null pattern ()');
 
 

Modified: trunk/t/compilers/pge/p6rules/cclass.t
==============================================================================
--- trunk/t/compilers/pge/p6rules/cclass.t      (original)
+++ trunk/t/compilers/pge/p6rules/cclass.t      Thu Feb  9 23:09:08 2006
@@ -94,7 +94,7 @@ p6rule_is  ('---x--', '<-[+\-]>?', 'nega
 p6rule_is  ('------', '<-[+\-]>?', 'negated optional escaped hyphen in range');
 
 # 'greater than' and 'less than' need no escapes
-p6rule_is  ('><', '^><[<]>', 'lt character class');
+p6rule_like('><', '^><[<]>', '/rule error/', 'lt character class');
 p6rule_is  ('><', '^<[>]><', 'gt character class',
         todo => 'parse error not yet implemented');
 p6rule_is  ('><', '^<[><]>**{2}', 'gt, lt character class');

Modified: trunk/t/compilers/pge/p6rules/metachars.t
==============================================================================
--- trunk/t/compilers/pge/p6rules/metachars.t   (original)
+++ trunk/t/compilers/pge/p6rules/metachars.t   Thu Feb  9 23:09:08 2006
@@ -120,7 +120,7 @@ p6rule_is  ("bcd", '<[a..d]>+ | <[b..e]>
 p6rule_is  ("bcd", '^ <[a..d]>+ | <[b..e]>+ $', 'alternation (|)');
 p6rule_is  ("bcd", '<[a..c]>+ | <[b..e]>+', 'alternation (|)');
 p6rule_is  ("bcd", '<[a..d]>+ | <[c..e]>+', 'alternation (|)');
-p6rule_like("bcd", 'b|', '/Missing term/', 'alternation (|) - null right arg 
illegal');
+p6rule_like("bcd", 'b|', '/rule error/', 'alternation (|) - null right arg 
illegal');
 p6rule_like("bcd", '|b', '/Missing term/', 'alternation (|) - null left arg 
illegal', todo => 'not yet implemented');
 p6rule_like("bcd", '|', '/Missing term/', 'alternation (|) - null both args 
illegal', todo => 'not yet implemented');
 p6rule_is  ("|", '\|', 'alternation (|) - literal must be escaped');
@@ -133,7 +133,7 @@ p6rule_is  ("bcd", '<[a..d]>+ & <[b..e]>
 p6rule_is  ("bcd", '^ <[a..d]>+ & <[b..e]>+ $', 'conjunction (&)');
 p6rule_is  ("bcd", '<[a..c]>+ & <[b..e]>+', 'conjunction (&)');
 p6rule_is  ("bcd", '<[a..d]>+ & <[c..e]>+', 'conjunction (&)');
-p6rule_like("bcd", 'b&', '/Missing term/', 'conjunction (&) - null right arg 
illegal');
+p6rule_like("bcd", 'b&', '/rule error/', 'conjunction (&) - null right arg 
illegal');
 p6rule_like("bcd", '&b', '/Missing term/', 'conjunction (&) - null left arg 
illegal', todo => 'not yet implemented');
 p6rule_like("bcd", '&', '/Missing term/', 'conjunction (&) - null both args 
illegal', todo => 'not yet implemented');
 p6rule_is  ("&", '\&', 'conjunction (&) - literal must be escaped');

Reply via email to