Strumenta / pylasu

Apache License 2.0
24 stars 4 forks source link

Introduce the PylasuParser class #18

Open ftomassetti opened 1 year ago

ftomassetti commented 1 year ago

It could look similar to this:

class MyListener(ErrorListener):
    issues: list[Issue]
    issue_type: IssueType

    def __init__(self, issues: list[Issue], issue_type: IssueType):
        self.issues = issues
        self.issue_type = issue_type

    def syntaxError(self, recognizer, offendingSymbol, line, column, msg, e):
        self.issues.append(Issue(message=str(msg),
                                 type=self.issue_type, position=Position(start=Point(line=line, column=column),
                                                                         end=Point(line=line, column=column))))

    def reportAmbiguity(self, recognizer, dfa, startIndex, stopIndex, exact, ambigAlts, configs):
        pass

    def reportAttemptingFullContext(self, recognizer, dfa, startIndex, stopIndex, conflictingAlts, configs):
        pass

    def reportContextSensitivity(self, recognizer, dfa, startIndex, stopIndex, prediction, configs):
        pass

class PylasuParser:

    def __init__(lexer_class, parser_class):
        self.lexer_class= lexer_class
        self.parser_class = parser_class

    def parse(self, code: str) -> Result:
        issues = []

        input = InputStream(code)

        lexer = self.lexer_class(input)
        lexer.removeErrorListeners()
        lexer.addErrorListener(MyListener(issues, IssueType.LEXICAL))

        token_stream = CommonTokenStream(lexer)
        parser = self.parser_class(token_stream)
        parser.removeErrorListeners()
        parser.addErrorListener(MyListener(issues, IssueType.SYNTACTIC))
        parse_tree = parser.root_rule() # I am not sure how we can invoke the root rule through reflection

        ast = parse_tree.to_ast(issues)
        ast.assign_parents()

        return Result(root=ast, issues=issues)