def test_parse_recursive(self): parser = easyparse.Grammar() parser.digits = (easyparse.parse('0') | easyparse.parse('1')) +\ parser.digits | easyparse.ignore('') ok, result = parser.digits.parse('101') self.assertTrue(ok) self.assertEqual(['1', '0', '1'], result)
def test_create_virtual_rule_in_parser(self): parser = easyparse.Grammar() parser.number = parser.digit + (parser.number | easyparse.ignore('')) parser.digit = easyparse.parse('0') | easyparse.parse('1') exp_value = (True, ['0', '1', '0', '1']) act_value = parser.number.parse('0101') self.assertEqual(exp_value, act_value)
def test_print_backtrace_disjunction(self): rule = easyparse.DisjunctionRule(easyparse.parse('a'), easyparse.parse('b')) ok, backtrace = rule.parse('c') self.assertFalse(ok) backtrace_string = self._print_backtrace_to_string(backtrace) exp_backtrace_string = '\n'.join([ "<Unnamed>: Disjunction: Failed", " <Unnamed>: Pattern: Failed to match 'a'", " <Unnamed>: Pattern: Failed to match 'b'\n" ]) self.assertEqual(exp_backtrace_string, backtrace_string)
def test_print_backtrace_disjunction(self): rule = easyparse.DisjunctionRule( easyparse.parse('a'), easyparse.parse('b')) ok, backtrace = rule.parse('c') self.assertFalse(ok) backtrace_string = self._print_backtrace_to_string(backtrace) exp_backtrace_string = '\n'.join([ "<Unnamed>: Disjunction: Failed", " <Unnamed>: Pattern: Failed to match 'a'", " <Unnamed>: Pattern: Failed to match 'b'\n"]) self.assertEqual(exp_backtrace_string, backtrace_string)
def test_print_backtrace_named_conjunction(self): g = easyparse.Grammar() g.start = easyparse.ConjunctionRule(g.a_rule, g.num) g.a_rule = easyparse.parse('a') g.num = easyparse.parse('0') ok, backtrace = g.start.parse('a1') self.assertFalse(ok) backtrace_string = self._print_backtrace_to_string(backtrace) exp_backtrace_string = '\n'.join([ "start: Conjunction: Failed", " a_rule: Pattern: Matched 'a'", " num: Pattern: Failed to match '0'\n" ]) self.assertEqual(exp_backtrace_string, backtrace_string)
def test_print_backtrace_named_conjunction(self): g = easyparse.Grammar() g.start = easyparse.ConjunctionRule( g.a_rule, g.num) g.a_rule = easyparse.parse('a') g.num = easyparse.parse('0') ok, backtrace = g.start.parse('a1') self.assertFalse(ok) backtrace_string = self._print_backtrace_to_string(backtrace) exp_backtrace_string = '\n'.join([ "start: Conjunction: Failed", " a_rule: Pattern: Matched 'a'", " num: Pattern: Failed to match '0'\n"]) self.assertEqual(exp_backtrace_string, backtrace_string)
def _make_dict_grammar(self): parser = easyparse.Grammar() parser.dict_rule = easyparse.ignore('{') + (parser.item_tuple_list | easyparse.ignore('')) + easyparse.ignore('}') > dict parser.item_tuple_list = parser.item_tuple + (easyparse.ignore(',') + parser.item_tuple_list | easyparse.ignore('')) parser.item_tuple = parser.item + easyparse.ignore(':') + parser.item > tuple parser.item = easyparse.parse(re='[0-9]') > int return parser
def _make_list_grammar(self): parser = easyparse.Grammar() parser.list_rule = easyparse.ignore('[') + ( parser.list_items | easyparse.ignore('')) + easyparse.ignore(']') > list parser.list_items = parser.item + ( easyparse.ignore(',') + parser.list_items | easyparse.ignore('')) parser.item = easyparse.parse(re='[0-9]') > int return parser
def test_print_multiple_disjunction_levels(self): g = easyparse.Grammar() g.top = easyparse.parse('a') | g.inner g.inner = easyparse.parse('b') + g.inner_inner g.inner_inner = easyparse.parse('c') | easyparse.parse('d') ok, backtrace = g.top.parse('bq') self.assertFalse(ok) backtrace_string = self._print_backtrace_to_string(backtrace) exp_backtrace_string = '\n'.join([ "top: Disjunction: Failed", " <Unnamed>: Pattern: Failed to match 'a'", " inner: Conjunction: Failed", " <Unnamed>: Pattern: Matched 'b'", " inner_inner: Disjunction: Failed", " <Unnamed>: Pattern: Failed to match 'c'", " <Unnamed>: Pattern: Failed to match 'd'\n" ]) self.assertEqual(exp_backtrace_string, backtrace_string)
def test_print_multiple_disjunction_levels(self): g = easyparse.Grammar() g.top = easyparse.parse('a') | g.inner g.inner = easyparse.parse('b') + g.inner_inner g.inner_inner = easyparse.parse('c') | easyparse.parse('d') ok, backtrace = g.top.parse('bq') self.assertFalse(ok) backtrace_string = self._print_backtrace_to_string(backtrace) exp_backtrace_string = '\n'.join([ "top: Disjunction: Failed", " <Unnamed>: Pattern: Failed to match 'a'", " inner: Conjunction: Failed", " <Unnamed>: Pattern: Matched 'b'", " inner_inner: Disjunction: Failed", " <Unnamed>: Pattern: Failed to match 'c'", " <Unnamed>: Pattern: Failed to match 'd'\n"]) self.assertEqual(exp_backtrace_string, backtrace_string)
def _make_dict_grammar(self): parser = easyparse.Grammar() parser.dict_rule = easyparse.ignore('{') + ( parser.item_tuple_list | easyparse.ignore('')) + easyparse.ignore('}') > dict parser.item_tuple_list = parser.item_tuple + ( easyparse.ignore(',') + parser.item_tuple_list | easyparse.ignore('')) parser.item_tuple = parser.item + easyparse.ignore( ':') + parser.item > tuple parser.item = easyparse.parse(re='[0-9]') > int return parser
def _make_method_call_grammar(self): grammar = easyparse.Grammar() grammar.start = easyparse.null + grammar.method_call grammar.method_call = grammar.method_object + grammar.arglist grammar.method_object = grammar.instance_name ^\ easyparse.ignore('.') ^\ grammar.method_name grammar.instance_name = grammar.identifier grammar.method_name = grammar.identifier grammar.arglist = easyparse.ignore('(') + \ easyparse.join_ws(grammar.arg, easyparse.ignore(',')) + \ easyparse.ignore(')') > tuple grammar.arg = grammar.identifier grammar.identifier = easyparse.parse(re=r'[a-zA-Z_]+') return grammar
def test_print_backtrace_named_rule_with_transformation(self): """Test the failure of a rule with a transformation.""" g = easyparse.Grammar() g.term = g.num + easyparse.ignore('+') + g.term | easyparse.eof > \ sum g.num = easyparse.parse(re='[0-9]+') > int ok, backtrace = g.term.parse('1+q') self.assertFalse(ok) backtrace_string = self._print_backtrace_to_string(backtrace) exp_backtrace_string = '\n'.join([ "term: Disjunction: Failed", " <Unnamed>: Conjunction: Failed", " num: RegularExpression: Matched '1'", " <Unnamed>: Pattern: Matched '[]'", # [] means Ignored " term: Disjunction: Failed", " <Unnamed>: Conjunction: Failed", " num: RegularExpression: Failed to match '[0-9]+'", " <Unnamed>: Eof: Failed", " <Unnamed>: Eof: Failed\n"]) self.assertEqual(exp_backtrace_string, backtrace_string)
def test_print_backtrace_named_rule_with_transformation(self): """Test the failure of a rule with a transformation.""" g = easyparse.Grammar() g.term = g.num + easyparse.ignore('+') + g.term | easyparse.eof > \ sum g.num = easyparse.parse(re='[0-9]+') > int ok, backtrace = g.term.parse('1+q') self.assertFalse(ok) backtrace_string = self._print_backtrace_to_string(backtrace) exp_backtrace_string = '\n'.join([ "term: Disjunction: Failed", " <Unnamed>: Conjunction: Failed", " num: RegularExpression: Matched '1'", " <Unnamed>: Pattern: Matched '[]'", # [] means Ignored " term: Disjunction: Failed", " <Unnamed>: Conjunction: Failed", " num: RegularExpression: Failed to match '[0-9]+'", " <Unnamed>: Eof: Failed", " <Unnamed>: Eof: Failed\n" ]) self.assertEqual(exp_backtrace_string, backtrace_string)
def test_parse_regex_string(self): parser = easyparse.Grammar() parser.string = easyparse.parse(re='"[^"]*"') ok, result = parser.string.parse('"abc"') self.assertTrue(ok) self.assertEqual(result, '"abc"')
def test_parse_re(self): rule = easyparse.parse(re=r'[0-9]') self.assertEqual((True, '8'), rule.parse('8')) self.assertFalse(rule.parse('a')[0])
def test_parse_large_stack_with_many(self): rule = easyparse.many(easyparse.parse('a')) ok, result = rule.parse('a' * 1000) self.assertTrue(ok) self.assertEqual(['a'] * 1000, result)
def test_parse_delegates_to_pattern_rule(self): rule = easyparse.parse('010') self.assertEqual((True, '010'), rule.parse('010')) self.assertFalse(rule.parse('01')[0])
def test_eof_with_preceding_whitespace(self): rule = easyparse.parse('a') + easyparse.EofRule() self.assertEqual((True, ['a']), rule.parse('a '))
def test_exception_in_transformation(self): rule = easyparse.TransformationRule(easyparse.parse('a'), int) ok, backtrace = rule.parse('a') self.assertFalse(ok) self.assertEqual(('', 'Transformation', 'a'), backtrace)
def test_parse_digit(self): parser = easyparse.Grammar() parser.digit = easyparse.parse('0') > int ok, result = parser.digit.parse('0') self.assertTrue(ok) self.assertEqual(result, 0)
def test_parse_large_stack_with_join(self): rule = easyparse.join(easyparse.parse('a'), easyparse.ignore(';')) ok, result = rule.parse('a;' * 999 + 'a') self.assertTrue(ok) self.assertEqual(['a'] * 1000, result)
def test_exception_in_named_transformation(self): g = easyparse.Grammar() g.integer = easyparse.TransformationRule(easyparse.parse('a'), int) ok, backtrace = g.integer.parse('a') self.assertFalse(ok) self.assertEqual(('integer', 'Transformation', 'a'), backtrace)
def test_eof_ignoring_preceding_whitespace(self): rule = easyparse.parse('a') ^ easyparse.EofRule() self.assertEqual(False, rule.parse('a ')[0])
def test_ignore_in_conjunction_is_ignored(self): rule = easyparse.ignore('0') + easyparse.parse('1') self.assertEqual((True, ['1']), rule.parse('01')) self.assertFalse(rule.parse('10')[0])
def _make_list_grammar(self): parser = easyparse.Grammar() parser.list_rule = easyparse.ignore('[') + (parser.list_items | easyparse.ignore('')) + easyparse.ignore(']') > list parser.list_items = parser.item + (easyparse.ignore(',') + parser.list_items | easyparse.ignore('')) parser.item = easyparse.parse(re='[0-9]') > int return parser