[Laszlo-checkins] r7761 - in openlaszlo/branches/devildog: WEB-INF/lps/server/sc/src/org/openlaszlo/sc test

dda@openlaszlo.org dda at openlaszlo.org
Mon Jan 7 14:34:49 PST 2008


Author: dda
Date: 2008-01-07 14:34:31 -0800 (Mon, 07 Jan 2008)
New Revision: 7761

Modified:
   openlaszlo/branches/devildog/WEB-INF/lps/server/sc/src/org/openlaszlo/sc/Parser.jjt
   openlaszlo/branches/devildog/test/optargs.lzx
Log:
Change 20080107-dda-C by dda at lester.local on 2008-01-07 16:44:28 EST
    in /Users/dda/laszlo/src/svn/openlaszlo/branches/devildog
    for http://svn.openlaszlo.org/openlaszlo/branches/devildog

Summary: SWF9: Fix grammar glitches in support for ...rest and optional parameters

New Features:

Bugs Fixed: LPP-5234

Technical Reviewer: ptw (pending)
QA Reviewer: hminsky (pending)
Doc Reviewer: (pending)

Documentation:

Release Notes:

Details:
    Previously, parsing of functions with optional or variable parameters had glitches.
    The known problems were that seeing a 'public' (and presumably any visibility keyword)
    before function caused a function with optional parameters to give an error.
    Also, if the function was the first item in the class (before any var) this would cause
    an error.  To fix this, I chose to simplify the grammar.  Before, the rules that
    any optional parameters must appear after regular parameters, and that the vararg parameter
    must appear last was built into the rules of the grammar.  This made the grammar complicated,
    and required extra LOOKAHEAD macros to resolve ambigulities.  Now the grammar is simple,
    and the rules for the ordering of kinds of parameters are enforced after
    the parsing for each element is complete.  All the strange error cases related to this part
    of the grammar now appear resolved.

Tests:
    Tried the two cases reported by Henry: 'public' appearing before function with opt args,
    and function with opt args appearing first in a class.

    Tried the test/optargs.lzs case for coverage of legal cases.

    Added some (commented) illegal cases in test/optargs.lzs to test coverage for illegal cases.



Modified: openlaszlo/branches/devildog/WEB-INF/lps/server/sc/src/org/openlaszlo/sc/Parser.jjt
===================================================================
--- openlaszlo/branches/devildog/WEB-INF/lps/server/sc/src/org/openlaszlo/sc/Parser.jjt	2008-01-07 22:34:04 UTC (rev 7760)
+++ openlaszlo/branches/devildog/WEB-INF/lps/server/sc/src/org/openlaszlo/sc/Parser.jjt	2008-01-07 22:34:31 UTC (rev 7761)
@@ -67,6 +67,31 @@
         //    sn.setEndLocation(t.endLine, t.endColumn);
         //}
     }
+
+    public static class FormalParameterState {
+        private boolean hasRest = false;
+        private boolean hasInit = false;
+        private Token token;
+        public void setToken(Token t) {
+            token = t;
+        }
+        public void checkRestParameter() {
+            if (hasRest)
+                throw new ParseException(token, "multiple ...rest parameters not allowed");
+            hasRest = true;
+        }
+        public void checkInitParameter() {
+            if (hasRest)
+                throw new ParseException(token, "...rest parameter must be last");
+            hasInit = true;
+        }
+        public void checkRegularParameter() {
+            if (hasRest)
+                throw new ParseException(token, "...rest parameter must be last");
+            if (hasInit)
+                throw new ParseException(token, "regular parameters not allowed after optional parameters");
+        }
+    }
 }
 PARSER_END(Parser)
 
@@ -903,42 +928,43 @@
     Block()
 }
 
-ASTFormalParameterList FormalParameterList() #FormalParameterList : {}
+ASTFormalParameterList FormalParameterList() #FormalParameterList : {FormalParameterState fstate = new FormalParameterState(); Token t;}
 {
-     "(" [FormalParameters()] ")" 
+     t="(" {fstate.setToken(t);}
+       [ FormalParameter(fstate) ( "," FormalParameter(fstate) )* ] ")" 
      { return jjtThis; }
 }
 
-void FormalParameters() : {}
+void FormalParameter(FormalParameterState fstate) #void : {ASTIdentifier id; boolean hasRest = false; boolean hasInit = false;}
 {
-    FormalRestParameter()
-|   LOOKAHEAD(FormalParameter() ("," | ")")) FormalParameter()
-      (LOOKAHEAD("," FormalParameter() ("," | ")")) "," FormalParameter())*
-      (LOOKAHEAD("," FormalInitParameter()) "," FormalInitParameter())*
-      ["," FormalRestParameter()]
-|   FormalInitParameter()
-      (LOOKAHEAD("," FormalInitParameter()) "," FormalInitParameter())*
-      ["," FormalRestParameter()]
+  (
+    "..." id = FormalParameterIdentifier()
+    {
+        fstate.setToken(getToken(0));
+        id.setEllipsis(true);
+        hasRest = true;
+    }
+  | FormalParameterIdentifier()
+    [ "=" FormalInitializer()
+      {
+          fstate.setToken(getToken(0));
+          hasInit = true;
+      }
+    ]
+  )
+  {
+    if (hasRest)
+      fstate.checkRestParameter();
+    else if (hasInit)
+      fstate.checkInitParameter();
+    else
+      fstate.checkRegularParameter();
+  }
 }
 
-void FormalRestParameter() #void : {ASTIdentifier id;}
-{
-    "..." id = FormalParameterIdentifier()  { id.setEllipsis(true); }
-}
-
-void FormalParameter() #void : {ASTIdentifier id;}
-{
-    id = FormalParameterIdentifier()  { id.setEllipsis(false); }
-}
-
-void FormalInitParameter() #void : {}
-{
-    FormalParameter() FormalInitializer()
-}
-
 void FormalInitializer() #FormalInitializer : {}
 {
-     "=" AssignmentExpression()
+     AssignmentExpression()
 }
 
 ASTIdentifier FormalParameterIdentifier() #void : {ASTIdentifier id; ASTIdentifier.Type type;}

Modified: openlaszlo/branches/devildog/test/optargs.lzx
===================================================================
--- openlaszlo/branches/devildog/test/optargs.lzx	2008-01-07 22:34:04 UTC (rev 7760)
+++ openlaszlo/branches/devildog/test/optargs.lzx	2008-01-07 22:34:31 UTC (rev 7761)
@@ -43,6 +43,14 @@
   return 'f4(' + w + ',' + x + ',' + y + ',' + z + ',' + rest + ')';
 }
 
+// These can be uncommented to check error cases.
+//function xx1(...x, y) { }
+//function xx2(...x, ...y) { }
+//function xx3(...x, y = null) { }
+//function xx4(x = null, ...y, z) { }
+//function xx5(x = null, z) { }
+// function xx6(x = null, z, w = null) { }
+
 function show(x) {
    Debug.write(x);
 }
@@ -79,7 +87,7 @@
 
 </script>
 <!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
-* Copyright 2007 Laszlo Systems, Inc.  All Rights Reserved.                   *
+* Copyright 2007-2008 Laszlo Systems, Inc.  All Rights Reserved.              *
 * Use is subject to license terms.                                            *
 * X_LZ_COPYRIGHT_END ****************************************************** -->
 </canvas>



More information about the Laszlo-checkins mailing list