2 files changed, 129 insertions(+), 1 deletion(-)
viff/sfdl/grammar.py           |   13 ++++
viff/test/sfdl/test_grammar.py |  117 ++++++++++++++++++++++++++++++++++++++++


# HG changeset patch
# User Martin Geisler <[EMAIL PROTECTED]>
# Date 1227518457 -3600
# Node ID 188dabcb4cdd7efeab8db6d88b26ef81c1348656
# Parent  bc1b37d69c6193ea1b657675ec20a1c48dd168fa
Assignment, if and for statements.

diff --git a/viff/sfdl/grammar.py b/viff/sfdl/grammar.py
--- a/viff/sfdl/grammar.py
+++ b/viff/sfdl/grammar.py
@@ -16,7 +16,7 @@
 # License along with VIFF. If not, see <http://www.gnu.org/licenses/>.
 
 from pyparsing import Suppress, Word, Keyword, ZeroOrMore, Optional, Group, \
-    Forward, delimitedList, \
+    OneOrMore, Forward, delimitedList, \
     oneOf, operatorPrecedence, opAssoc, \
     cppStyleComment, alphas, alphanums, nums
 
@@ -64,6 +64,17 @@
                                     (oneOf("== !="),     2, opAssoc.LEFT),
                                     (oneOf("&& || ! ^"), 2, opAssoc.LEFT)])
 
+        self.stm = stm = Forward()
+        self.assign_stm = assign_stm = qual_ident + EQUAL + expr + SCOLON
+        self.if_stm = if_stm = Keyword("if") + Group(LPAREN + expr + RPAREN) + 
stm \
+            + Optional(Keyword("else") + stm)
+        self.for_stm = for_stm = Keyword("for") + LPAREN \
+            + Group(ident + EQUAL + const_expr) \
+            + Keyword("to") + Group(const_expr) + RPAREN + stm
+        self.block_stm = block_stm = LCURLY + OneOrMore(stm) + RCURLY
+        stm << Group(assign_stm | if_stm | for_stm | block_stm)
+
+
         self.program = program = Keyword("program") + ident \
             + LCURLY + RCURLY
         program.ignore(cppStyleComment)
diff --git a/viff/test/sfdl/test_grammar.py b/viff/test/sfdl/test_grammar.py
--- a/viff/test/sfdl/test_grammar.py
+++ b/viff/test/sfdl/test_grammar.py
@@ -163,5 +163,122 @@
                             ['h', 'z', '[', '1', ']']]
                            ]])
 
+    def test_assign_stm(self):
+        self.assertParse(self.grammar.assign_stm, "x = 1;", ['x', '1'])
+        self.assertParse(self.grammar.assign_stm, "x[1] = 1;",
+                         ['x', '[', '1', ']', '1'])
+        self.assertParse(self.grammar.assign_stm, "x.y = a[1] * b.c;",
+                         ['x', '.', 'y',
+                          ['a', '[', '1', ']', '*', 'b', '.', 'c']])
+
+    def test_if_stm(self):
+        self.assertParse(self.grammar.if_stm, "if (x == 10) y = false;",
+                         ['if', [['x', '==', '10']], ['y', 'false']])
+        self.assertParse(self.grammar.if_stm, "if (x == 10) { y = false; }",
+                         ['if', [['x', '==', '10']], [['y', 'false']]])
+        self.assertParse(self.grammar.if_stm,
+                         "if (x == 10) { y = false; z = 0; }",
+                         ['if', [['x', '==', '10']],
+                          [['y', 'false'],
+                           ['z', '0']]])
+
+    def test_if_else_stm(self):
+        self.assertParse(self.grammar.if_stm,
+                         "if (x == 10) y = false; else z = false;",
+                         ['if', [['x', '==', '10']],
+                          ['y', 'false'],
+                          'else',
+                          ['z', 'false']])
+
+        src = """
+               if (x < 10) {
+                 y = false;
+                 z = 0;
+               } else
+                 x = x + 1;
+              """
+        self.assertParse(self.grammar.if_stm, src,
+                         ['if', [['x', '<', '10']],
+                          [['y', 'false'],
+                           ['z', '0']],
+                          'else',
+                          ['x', ['x', '+', '1']]])
+
+    def test_nested_if_stm(self):
+        src = """
+               if (x < 10) {
+                   y = false;
+                   if (x < 5) {
+                       z = 0;
+                   } else {
+                       x = x + 1;
+                   }
+               }
+              """
+        self.assertParse(self.grammar.if_stm, src,
+                         ['if', [['x', '<', '10']],
+                          [['y', 'false'],
+                           ['if', [['x', '<', '5']],
+                            [['z', '0']],
+                            'else',
+                            [['x', ['x', '+', '1']]]]]])
+
+        src = """
+               if (x < 10) {
+                   y = false;
+                   if (x < 5)
+                       z = 0;
+                   else
+                       x = x + 1;
+               }
+              """
+        self.assertParse(self.grammar.if_stm, src,
+                         ['if', [['x', '<', '10']],
+                          [['y', 'false'],
+                           ['if', [['x', '<', '5']],
+                            ['z', '0'],
+                            'else',
+                            ['x', ['x', '+', '1']]]]])
+
+    def test_dangling_else(self):
+        src = """
+               if (x < 10)
+                   if (x < 5)
+                       z = 0;
+                   else
+                       x = x + 1;
+              """
+        # The inner else should bind to the inner if.
+        self.assertParse(self.grammar.if_stm, src,
+                         ['if', [['x', '<', '10']],
+                          ['if', [['x', '<', '5']],
+                           ['z', '0'],
+                           'else',
+                           ['x', ['x', '+', '1']]]])
+
+    def test_for_stm(self):
+        self.assertParse(self.grammar.for_stm,
+                         "for (i = 0 to 10) { x[i] = 42; }",
+                         ['for', ['i', '0'], 'to', ['10'],
+                          [['x', '[', 'i', ']', '42']]])
+
+        src = """
+               for (i = MIN to MIN + 10) {
+                   b[i] = x[i] < x[i+1];
+                   y[i] = b[i] && z[i];
+               }
+              """
+        self.assertParse(self.grammar.for_stm, src,
+                         ['for', ['i', 'MIN'], 'to', [['MIN', '+', '10']],
+                          [['b', '[', 'i', ']',
+                            ['x', '[', 'i', ']',
+                             '<',
+                             'x', '[', ['i', '+', '1'], ']']],
+                           ['y', '[', 'i', ']',
+                            ['b', '[', 'i', ']',
+                             '&&',
+                             'z', '[', 'i', ']']]]])
+
+
 if SFDLGrammar is None:
     TestGrammar.skip = "Could not import SFDLGrammar, missing pyparsing?"
_______________________________________________
viff-patches mailing list
viff-patches@viff.dk
http://lists.viff.dk/listinfo.cgi/viff-patches-viff.dk

Reply via email to