def __call__(self, namespace, env, source, benchmark=False): if benchmark: now = time.time() print 'start parsing' parser = earley.Parser(self.init, self.nullable) stream = L2(CStream(source), self.symboltab) indent_stack = [] indent = 0 if stream.first is None else stream.first.start.col line = 0 if stream.first is None else stream.first.start.lno while stream.filled: if line < stream.first.start.lno: while stream.first.start.col < indent and 'dedent' in parser.expect: start = stream.first.start parser.step(Literal(start, start, 'dedent', '')) indent = indent_stack.pop() if stream.first.start.col < indent: raise Exception("Uneven indent at line %s" % stream.first.start) if stream.first.start.col == indent and 'newline' in parser.expect: start = stream.first.start parser.step(Literal(start, start, 'newline', '')) if stream.first.start.col > indent and 'indent' in parser.expect: start = stream.first.start parser.step(Literal(start, start, 'indent', '')) indent_stack.append(indent) indent = stream.first.start.col line = stream.first.start.lno expect = parser.expect token = stream.advance() parser.step(token) if len(parser.chart[-1]) == 0: if self.debug: print_result(parser) trail = format_expect(expect) raise Exception( "{0.lno}:{0.col}: parse error at {1.name} {1.value!r}\n{2}" .format(token.start, token, trail)) while 'dedent' in parser.expect: stop = token.stop parser.step(Literal(stop, stop, 'dedent', '')) if not parser.accept: if self.debug: print_result(parser) trail = format_expect(parser.expect) raise Exception( "{0.lno}:{0.col}: parse error at end of file\n{1}".format( stream.stream, trail)) if self.debug: print_result(parser) if benchmark: trav = time.time() print 'parsing took:', trav - now results = traverse(parser, parser.root, 0, len(parser.input), namespace, env) if benchmark: print 'traverse took:', time.time() - trav return results
return token.value == 'earley' and token.lsp == token.rsp == False grammar = [ #Rule('file', []), # XXX: fix a bug, if you use empty rule instead, it won't parse # XXX: verify that the bug fix works. Rule('file', ['term']), Rule('file', ['term', 'file']), Rule('term', ['symbol']), #Rule('term', ['leftparen', early, 'rightparen']), ] init, nullable = earley.simulate(grammar, 'file', True) source = open(sys.argv[1]).read() stream = L2(CStream(source), table) parser = earley.Parser(init, nullable) while stream.filled: token = stream.advance() parser.step(token) earley.print_result(parser) def traverse(parser, rule, start, stop): midresults = list(parser.chains(rule.rhs, start, stop)) for midresult in midresults: print start, stop, rule.lhs, midresult if len(midresults) > 1: raise Exception("ambiguity at {}:{}".format(start, stop)) for midresult in midresults: