2 files changed, 43 insertions(+), 2 deletions(-)
viff/sfdl/grammar.py           |   17 +++++++++++++++--
viff/test/sfdl/test_grammar.py |   28 ++++++++++++++++++++++++++++


# HG changeset patch
# User Martin Geisler <[EMAIL PROTECTED]>
# Date 1227518457 -3600
# Node ID d7a1eac0ed9675650ef09894e672cffcd554cc49
# Parent  be095927c9e007ef56652a475f524eea32c0515a
Parsing of expressions.

diff --git a/viff/sfdl/grammar.py b/viff/sfdl/grammar.py
--- a/viff/sfdl/grammar.py
+++ b/viff/sfdl/grammar.py
@@ -15,8 +15,8 @@
 # You should have received a copy of the GNU Lesser General Public
 # License along with VIFF. If not, see <http://www.gnu.org/licenses/>.
 
-from pyparsing import Suppress, Word, Keyword, ZeroOrMore, \
-    delimitedList, \
+from pyparsing import Suppress, Word, Keyword, ZeroOrMore, Optional, Group, \
+    Forward, delimitedList, \
     oneOf, operatorPrecedence, opAssoc, \
     cppStyleComment, alphas, alphanums, nums
 
@@ -26,6 +26,7 @@
         SCOLON = Suppress(";")
         EQUAL = Suppress("=")
         LCURLY, RCURLY = Suppress("{"), Suppress("}")
+        LPAREN, RPAREN = Suppress("("), Suppress(")")
 
         self.ident = ident = Word(alphas + "_", alphanums + "_")
 
@@ -36,6 +37,18 @@
         self.const_dec = const_dec \
             = Keyword("const") + ident + EQUAL + const_expr + SCOLON
 
+        self.expr = expr = Forward()
+        self.qual_ident = qual_ident = ident \
+            + ZeroOrMore(("[" + expr + "]") | ("." + ident))
+        self.func_call = func_call \
+            = Group(ident + LPAREN + Optional(delimitedList(expr)) + RPAREN)
+        expr << operatorPrecedence(Word(nums) | func_call | qual_ident,
+                                   [(oneOf("* /"),       2, opAssoc.LEFT),
+                                    (oneOf("+ -"),       2, opAssoc.LEFT),
+                                    (oneOf("< > <= >="), 2, opAssoc.LEFT),
+                                    (oneOf("== !="),     2, opAssoc.LEFT),
+                                    (oneOf("&& || ! ^"), 2, opAssoc.LEFT)])
+
         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
@@ -92,5 +92,33 @@
         self.assertNoParse(self.grammar.const_dec, "const x;")
         self.assertNoParse(self.grammar.const_dec, "const x 123;")
 
+    def test_qual_ident(self):
+        self.assertParse(self.grammar.qual_ident, "x.y", ['x', '.', 'y'])
+        self.assertParse(self.grammar.qual_ident, "x[10]",
+                         ['x', '[', '10', ']'])
+        self.assertParse(self.grammar.qual_ident, "x[y+1].foo",
+                         ['x', '[', ['y', '+', '1'], ']', '.', 'foo'])
+
+    def test_func_call(self):
+        self.assertParse(self.grammar.func_call, "foo()", [['foo']])
+        self.assertParse(self.grammar.func_call, "foo(10)", [['foo', '10']])
+        self.assertParse(self.grammar.func_call, "foo(10+x)",
+                         [['foo', ['10', '+', 'x']]])
+
+    def test_expr_atom(self):
+        self.assertParse(self.grammar.expr, "123", ['123'])
+        self.assertParse(self.grammar.expr, "foo", ['foo'])
+
+    def test_expr(self):
+        self.assertParse(self.grammar.expr, "1 + 2 * 3 / 4",
+                         [['1', '+', ['2', '*', '3', '/', '4']]])
+        self.assertParse(self.grammar.expr, "123 + f(10) < g(x.y) * h(z[1])",
+                         [[['123', '+', ['f', '10']],
+                           '<',
+                           [['g', 'x', '.', 'y'],
+                            '*',
+                            ['h', 'z', '[', '1', ']']]
+                           ]])
+
 if SFDLGrammar is None:
     TestGrammar.skip = "Could not import SFDLGrammar, missing pyparsing?"
_______________________________________________
viff-patches mailing list
[email protected]
http://lists.viff.dk/listinfo.cgi/viff-patches-viff.dk

Reply via email to