예제 #1
0
파일: gvm.py 프로젝트: alurin/gvm
def main():
    grammar = Grammar()

    # core grammar
    grammar.extend(create_core_grammar())

    # combinator grammars
    grammar.extend(create_combinator_grammar())

    # add macro grammar. e.g. expr
    grammar.add_parser('macro',
                       'name:Name "::=" combinator: combinator_sequence')

    # # dump grammar
    # dump_grammar(sys.stdout, grammar)

    content = """
expr ::= 1 2 3 ; |

def main(): pass
""".strip()

    #
    scanner = DefaultScanner(grammar, '<example>', content)
    parser = Parser(scanner)
    try:
        parser.parse(grammar.parselets['macro'])
    except ParserError as ex:
        ex.to_stream(create_writer(sys.stderr), content)
        exit(1)
예제 #2
0
파일: grammar.py 프로젝트: alurin/gvm
    def __call__(self, parser: Parser, priority: int) -> ParseletResult:
        parselets = self.prefixes.get(parser.current_token.id, ())
        if not parselets:
            raise parser.error(self.prefix_tokens)
        left, error = parser.choice(parselets)

        while True:
            parselets = tuple(
                itertools.takewhile(
                    lambda parselet: priority < parselet.priority,
                    self.postfixes.get(parser.current_token.id, ())))
            if not parselets:
                break

            try:
                left, last_error = parser.choice(parselets, left)
            except ParserError as last_error:
                error = ParserError.merge(error, last_error)
                break
            else:
                error = ParserError.merge(error, last_error)

        return left, error
예제 #3
0
파일: combinators.py 프로젝트: alurin/gvm
 def __call__(self, parser: Parser, context: Parselet) -> CombinatorResult:
     items = []
     error = None
     namespace = {}
     while True:
         try:
             with parser.backtrack():
                 result, last_namespace, last_error = self.combinator(
                     parser, context)
         except ParserError as last_error:
             error = ParserError.merge(error, last_error)
             break
         else:
             error = ParserError.merge(error, last_error)
             items.append(result)
             for name, value in last_namespace.items():
                 namespace[name] = [*namespace[name], *value
                                    ] if name in namespace else value
     return tuple(items), namespace, error
예제 #4
0
파일: test_parser.py 프로젝트: alurin/gvm
def parse_expr(grammar: Grammar, content: str):
    scanner = DefaultScanner(grammar, '<example>', content)
    parser = Parser(scanner)
    result = parser.parse(grammar.parselets['expr'])
    return result
예제 #5
0
파일: combinators.py 프로젝트: alurin/gvm
 def __call__(self, parser: Parser, context: Parselet) -> CombinatorResult:
     result, error = parser.parselet(self.parser_id, self.priority)
     return result, {}, error
예제 #6
0
파일: combinators.py 프로젝트: alurin/gvm
 def __call__(self, parser: Parser, context: Parselet) -> CombinatorResult:
     return parser.consume(self.token_id), {}, None
예제 #7
0
파일: combinators.py 프로젝트: alurin/gvm
 def __call__(self, parser: Parser, context: Parselet) -> CombinatorResult:
     with parser.backtrack():
         try:
             return self.combinator(parser, context)
         except ParserError as error:
             return None, {}, error
예제 #8
0
def parse_combinator(content: str):
    scanner = DefaultScanner(combinator_grammar, '<example>', content)
    parser = Parser(scanner)
    return parser.parse(combinator_grammar.parselets['combinator_sequence'])
예제 #9
0
파일: grammar.py 프로젝트: alurin/gvm
 def __call__(self, parser: Parser, priority: int) -> ParseletResult:
     return parser.choice(self.__parselets)