Beispiel #1
0
def generate_parser(start_symbol, productions, error_examples):
    """Generates a parser from grammar, and applies error_examples.

  Arguments:
      start_symbol: the start symbol of the grammar (a string)
      productions: a list of parser_types.Production in the grammar
      error_examples: A list of (source tokens, error message, source text)
          tuples.

  Returns:
      A parser.

  Raises:
      ParserGenerationError: There is a problem generating the parser.
  """
    parser = lr1.Grammar(start_symbol, productions).parser()
    if parser.conflicts:
        raise ParserGenerationError("\n".join(
            [str(c) for c in parser.conflicts]))
    for example in error_examples:
        mark_result = parser.mark_error(example[0], example[1], example[2])
        if mark_result:
            raise ParserGenerationError(
                "error marking example: {}\nExample:\n{}".format(
                    mark_result, example[3]))
    return parser
Beispiel #2
0
 def test_grammar_with_empty_rhs(self):
     grammar = lr1.Grammar(
         "S",
         _parse_productions("""S -> A B
                                                 A -> a A
                                                 A ->
                                                 B -> b"""))
     parser = grammar.parser()
     self.assertFalse(parser.conflicts)
     self.assertTrue(parser.parse(_tokenize("ab")).parse_tree)
     self.assertTrue(parser.parse(_tokenize("b")).parse_tree)
     self.assertTrue(parser.parse(_tokenize("aab")).parse_tree)
Beispiel #3
0
 def test_grammar_with_reduce_reduce_conflicts(self):
     grammar = lr1.Grammar(
         "S",
         _parse_productions("""S -> A c
                                                 S -> B c
                                                 A -> a
                                                 B -> a"""))
     parser = grammar.parser()
     self.assertEqual(len(parser.conflicts), 1)
     # parser.conflicts is a set
     for conflict in parser.conflicts:
         for action in conflict.actions:
             self.assertTrue(isinstance(action, lr1.Reduce))
Beispiel #4
0
 def test_grammar_with_shift_reduce_conflicts(self):
     grammar = lr1.Grammar(
         "S",
         _parse_productions("""S -> A B
                                                 A -> a
                                                 A ->
                                                 B -> a
                                                 B ->"""))
     parser = grammar.parser()
     self.assertEqual(len(parser.conflicts), 1)
     # parser.conflicts is a set
     for conflict in parser.conflicts:
         reduces = 0
         shifts = 0
         for action in conflict.actions:
             if isinstance(action, lr1.Reduce):
                 reduces += 1
             elif isinstance(action, lr1.Shift):
                 shifts += 1
         self.assertEqual(1, reduces)
         self.assertEqual(1, shifts)
Beispiel #5
0
    result = []
    for i in range(len(text)):
        result.append(
            Token(text[i], parser_types.make_location((1, i + 1), (1, i + 2))))
    return result


def _parse_productions(text):
    """Parses text into a grammar by calling Production.parse on each line."""
    return [parser_types.Production.parse(line) for line in text.splitlines()]


# Example grammar 4.54 from Aho, Sethi, Lam, Ullman (ASLU) p263.
_alsu_grammar = lr1.Grammar(
    "S",
    _parse_productions("""S -> C C
                                                      C -> c C
                                                      C -> d"""))

# Item sets corresponding to the above grammar, ASLU pp263-264.
_alsu_items = [
    _make_items("""S' -> . S, $
                  S -> . C C, $
                  C -> . c C, c
                  C -> . c C, d
                  C -> . d, c
                  C -> . d, d"""),
    _make_items("""S' -> S ., $"""),
    _make_items("""S -> C . C, $
                  C -> . c C, $
                  C -> . d, $"""),