import { Node } from "../model/model"; import { CharStream, Lexer, Parser as ANTLRParser, ParserRuleContext, Token, TokenStream } from "antlr4ng"; import { Issue } from "../validation"; import { Source } from "../model/position"; import { FirstStageParsingResult, LexingResult, ParsingResult, TokenCategory, TylasuANTLRToken, TylasuLexer, TylasuToken } from "./parsing"; import { ASTParser } from "./ast-parser"; export declare abstract class TokenFactory { categoryOf(t: Token): TokenCategory; abstract convertToken(t: Token): T; private convertTerminal; extractTokens(result: ParsingResult): LexingResult | undefined; } export declare class ANTLRTokenFactory extends TokenFactory { convertToken(t: Token): TylasuANTLRToken; } export declare const SYNTAX_ERROR = "parser.syntaxError"; export declare const MISMATCHED_INPUT = "parser.mismatchedinput"; export declare const TOKEN_RECOGNITION_ERROR = "lexer.tokenrecognitionerror"; export declare const INPUT_NOT_FULLY_CONSUMED = "parser.inputNotFullyConsumed"; export declare const ERROR_NODE_FOUND = "parser.errorNodeFound"; export declare abstract class TylasuANTLRLexer implements TylasuLexer { readonly tokenFactory: TokenFactory; constructor(tokenFactory: TokenFactory); /** * Creates the lexer. */ protected abstract createANTLRLexer(inputStream: CharStream): Lexer | undefined; /** * Performs "lexing" on the given code stream, i.e., it breaks it into tokens. */ lex(inputStream: CharStream, onlyFromDefaultChannel?: boolean): LexingResult; protected injectErrorCollectorInLexer(lexer: Lexer, issues: Issue[]): void; } export declare abstract class TylasuParser extends TylasuANTLRLexer implements ASTParser { /** * Creates the first-stage parser. */ protected abstract createANTLRParser(tokenStream: TokenStream): P; /** * Invokes the parser's root rule, i.e., the method which is responsible of parsing the entire input. * Usually this is the topmost rule, the one with index 0 (as also assumed by other libraries such as antlr4-c3), * so this method invokes that rule. If your grammar/parser is structured differently, or if you're using this to * parse only a portion of the input or a subset of the language, you have to override this method to invoke the * correct entry point. */ protected invokeRootRule(parser: P): C; /** * Transforms a parse tree into an AST (second parsing stage). */ protected abstract parseTreeToAst(parseTreeRoot: C, considerPosition: boolean, issues: Issue[], source?: Source): R | undefined; /** * Creates the first-stage lexer and parser. */ protected createParser(inputStream: CharStream, issues: Issue[]): P; protected createTokenStream(lexer: Lexer): TokenStream; /** * Checks the parse tree for correctness. If you're concerned about performance, you may want to override this to * do nothing. */ protected verifyParseTree(parser: ANTLRParser, issues: Issue[], root: ParserRuleContext): void; /** * Executes only the first stage of the parser, i.e., the production of a parse tree. Usually, you'll want to use * the [parse] method, that returns an AST which is simpler to use and query. */ parseFirstStage(inputStream: CharStream, measureLexingTime?: boolean): FirstStageParsingResult; protected postProcessAst(ast: R, issues: Issue[]): R; parse(code: string | CharStream, considerPosition?: boolean, measureLexingTime?: boolean, source?: Source): ParsingResult; /** * Traverses the AST to ensure that parent nodes are correctly assigned. * * If you assign the parents correctly when you build the AST, or you're not interested in tracking child-parent * relationships, you can override this method to do nothing to improve performance. */ protected assignParents(ast: R): void; protected injectErrorCollectorInParser(parser: ANTLRParser, issues: Issue[]): void; }