def testTrailingLookahead(self): """Lookahead at the end of a production is banned.""" tokenize = lexer.LexicalGrammar('IF ( X ) ELSE OTHER ;') grammar = gen.Grammar({ 'goal': [['stmt']], 'stmt': [ ['OTHER', ';'], [ 'IF', '(', 'X', ')', 'stmt', LookaheadRule(frozenset({'ELSE'}), False) ], ['IF', '(', 'X', ')', 'stmt', 'ELSE', 'stmt'], ], }) def stmt_0(): return ('stmt_0', 'OTHER', ';') def stmt_1(t): return ('stmt_1', 'IF', '(', 'X', ')', t) def stmt_2(t, e): return ('stmt_2', 'IF', '(', 'X', ')', t, 'ELSE', e) self.compile(tokenize, grammar) self.assertParse('IF(X) OTHER;', stmt_1(stmt_0())) self.assertParse('IF(X) OTHER; ELSE OTHER;', stmt_2(stmt_0(), stmt_0())) self.assertParse('IF(X) IF(X) OTHER; ELSE OTHER; ELSE OTHER;', stmt_2(stmt_2(stmt_0(), stmt_0()), stmt_0())) self.assertParse('IF(X) OTHER; ELSE IF(X) OTHER; ELSE OTHER;', stmt_2(stmt_0(), stmt_2(stmt_0(), stmt_0()))) self.assertParse('IF(X) IF(X) OTHER; ELSE OTHER;', stmt_1(stmt_2(stmt_0(), stmt_0())))
def testTrailingLookahead(self): """Lookahead at the end of a production is banned.""" grammar = gen.Grammar({ 'stmt': [ ['OTHER', ';'], ['IF', '(', 'X', ')', 'stmt', LookaheadRule(frozenset({'ELSE'}), False)], ['IF', '(', 'X', ')', 'stmt', 'ELSE', 'stmt'], ], }) self.assertRaisesRegex( ValueError, r"invalid grammar: lookahead restriction at end of production", lambda: gen.compile(grammar))