# -*- coding: utf-8 -*- ####################################################################### # Name: test_parsing_expressions # Purpose: Test for parsing expressions. # Author: Igor R. Dejanović <igor DOT dejanovic AT gmail DOT com> # Copyright: (c) 2014 Igor R. Dejanović <igor DOT dejanovic AT gmail DOT com> # License: MIT License ####################################################################### from unittest import TestCase from arpeggio import ParserPython, ZeroOrMore, OneOrMore, NoMatch, EOF, Optional, And, Not from arpeggio import RegExMatch as _ class TestParsingExpression(TestCase): def test_sequence(self): def grammar(): return ("a", "b", "c") parser = ParserPython(grammar) parsed = parser.parse("a b c") self.assertEqual(str(parsed), "abc") self.assertEqual(repr(parsed), "[ 'a' [0], 'b' [2], 'c' [4] ]") def test_ordered_choice(self): def grammar(): return ["a", "b", "c"], EOF parser = ParserPython(grammar) parsed = parser.parse("b") self.assertEqual(str(parsed), "b") self.assertEqual(repr(parsed), "[ 'b' [0], EOF [1] ]") parsed = parser.parse("c") self.assertEqual(str(parsed), "c") self.assertEqual(repr(parsed), "[ 'c' [0], EOF [1] ]") self.assertRaises(NoMatch, lambda: parser.parse("ab")) self.assertRaises(NoMatch, lambda: parser.parse("bb")) def test_zero_or_more(self): def grammar(): return ZeroOrMore("a"), EOF parser = ParserPython(grammar) parsed = parser.parse("aaaaaaa") self.assertEqual(str(parsed), "aaaaaaa") self.assertEqual(repr(parsed), "[ 'a' [0], 'a' [1], 'a' [2], 'a' [3], 'a' [4], 'a' [5], 'a' [6], EOF [7] ]") parsed = parser.parse("") self.assertEqual(str(parsed), "") self.assertEqual(repr(parsed), "[ EOF [0] ]") self.assertRaises(NoMatch, lambda: parser.parse("bbb")) def test_one_or_more(self): def grammar(): return OneOrMore("a") parser = ParserPython(grammar) parsed = parser.parse("aaaaaaa") self.assertEqual(str(parsed), "aaaaaaa") self.assertEqual(repr(parsed), "[ 'a' [0], 'a' [1], 'a' [2], 'a' [3], 'a' [4], 'a' [5], 'a' [6] ]") self.assertRaises(NoMatch, lambda: parser.parse("")) self.assertRaises(NoMatch, lambda: parser.parse("bbb")) def test_optional(self): def grammar(): return Optional("a"), "b", EOF parser = ParserPython(grammar) parsed = parser.parse("ab") self.assertEqual(str(parsed), "ab") self.assertEqual(repr(parsed), "[ 'a' [0], 'b' [1], EOF [2] ]") parsed = parser.parse("b") self.assertEqual(str(parsed), "b") self.assertEqual(repr(parsed), "[ 'b' [0], EOF [1] ]") self.assertRaises(NoMatch, lambda: parser.parse("aab")) self.assertRaises(NoMatch, lambda: parser.parse("")) # Syntax predicates def test_and(self): def grammar(): return "a", And("b"), ["c", "b"], EOF parser = ParserPython(grammar) parsed = parser.parse("ab") self.assertEqual(str(parsed), "ab") self.assertEqual(repr(parsed), "[ 'a' [0], 'b' [1], EOF [2] ]") # 'And' will try to match 'b' and fail so 'c' will never get matched self.assertRaises(NoMatch, lambda: parser.parse("ac")) # 'And' will not consume 'b' from the input so second 'b' will never match self.assertRaises(NoMatch, lambda: parser.parse("abb")) def test_not(self): def grammar(): return "a", Not("b"), ["b", "c"], EOF parser = ParserPython(grammar) parsed = parser.parse("ac") self.assertEqual(str(parsed), "ac") self.assertEqual(repr(parsed), "[ 'a' [0], 'c' [1], EOF [2] ]") # Not will will fail on 'b' self.assertRaises(NoMatch, lambda: parser.parse("ab")) # And will not consume 'c' from the input so 'b' will never match self.assertRaises(NoMatch, lambda: parser.parse("acb"))