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