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
