@@ -53,6 +53,7 @@ interface AssignmentElement {
5353
5454export interface BaseParser {
5555 rule ( rule : ParserRule , impl : RuleImpl ) : RuleResult ;
56+ getRule ( name : string ) : RuleResult | undefined ;
5657 alternatives ( idx : number , choices : Array < IOrAlt < any > > ) : void ;
5758 optional ( idx : number , callback : DSLMethodOpts < unknown > ) : void ;
5859 many ( idx : number , callback : DSLMethodOpts < unknown > ) : void ;
@@ -75,6 +76,9 @@ export abstract class AbstractLangiumParser implements BaseParser {
7576 protected readonly wrapper : ChevrotainWrapper ;
7677 protected _unorderedGroups : Map < string , boolean [ ] > = new Map < string , boolean [ ] > ( ) ;
7778
79+ protected allRules = new Map < string , RuleResult > ( ) ;
80+ protected mainRule ! : RuleResult ;
81+
7882 constructor ( services : LangiumCoreServices ) {
7983 this . lexer = services . parser . Lexer ;
8084 const tokens = this . lexer . definition ;
@@ -106,6 +110,10 @@ export abstract class AbstractLangiumParser implements BaseParser {
106110 abstract action ( $type : string , action : Action ) : void ;
107111 abstract construct ( ) : unknown ;
108112
113+ getRule ( name : string ) : RuleResult | undefined {
114+ return this . allRules . get ( name ) ;
115+ }
116+
109117 isRecording ( ) : boolean {
110118 return this . wrapper . IS_RECORDING ;
111119 }
@@ -129,7 +137,6 @@ export class LangiumParser extends AbstractLangiumParser {
129137 private readonly astReflection : AstReflection ;
130138 private readonly nodeBuilder = new CstNodeBuilder ( ) ;
131139 private stack : any [ ] = [ ] ;
132- private mainRule ! : RuleResult ;
133140 private assignmentMap = new Map < AbstractElement , AssignmentElement | undefined > ( ) ;
134141
135142 private get current ( ) : any {
@@ -146,17 +153,22 @@ export class LangiumParser extends AbstractLangiumParser {
146153 rule ( rule : ParserRule , impl : RuleImpl ) : RuleResult {
147154 const type = rule . fragment ? undefined : isDataTypeRule ( rule ) ? DatatypeSymbol : getTypeName ( rule ) ;
148155 const ruleMethod = this . wrapper . DEFINE_RULE ( withRuleSuffix ( rule . name ) , this . startImplementation ( type , impl ) . bind ( this ) ) ;
156+ this . allRules . set ( rule . name , ruleMethod ) ;
149157 if ( rule . entry ) {
150158 this . mainRule = ruleMethod ;
151159 }
152160 return ruleMethod ;
153161 }
154162
155- parse < T extends AstNode = AstNode > ( input : string ) : ParseResult < T > {
163+ parse < T extends AstNode = AstNode > ( input : string , options : { rule ?: string } = { } ) : ParseResult < T > {
156164 this . nodeBuilder . buildRootNode ( input ) ;
157165 const lexerResult = this . lexer . tokenize ( input ) ;
158166 this . wrapper . input = lexerResult . tokens ;
159- const result = this . mainRule . call ( this . wrapper , { } ) ;
167+ const ruleMethod = options . rule ? this . allRules . get ( options . rule ) : this . mainRule ;
168+ if ( ! ruleMethod ) {
169+ throw new Error ( options . rule ? `No rule found with name '${ options . rule } '` : 'No main rule available.' ) ;
170+ }
171+ const result = ruleMethod . call ( this . wrapper , { } ) ;
160172 this . nodeBuilder . addHiddenTokens ( lexerResult . hidden ) ;
161173 this . unorderedGroups . clear ( ) ;
162174 return {
@@ -424,7 +436,6 @@ export interface CompletionParserResult {
424436}
425437
426438export class LangiumCompletionParser extends AbstractLangiumParser {
427- private mainRule ! : RuleResult ;
428439 private tokens : IToken [ ] = [ ] ;
429440
430441 private elementStack : AbstractElement [ ] = [ ] ;
@@ -457,6 +468,7 @@ export class LangiumCompletionParser extends AbstractLangiumParser {
457468
458469 rule ( rule : ParserRule , impl : RuleImpl ) : RuleResult {
459470 const ruleMethod = this . wrapper . DEFINE_RULE ( withRuleSuffix ( rule . name ) , this . startImplementation ( impl ) . bind ( this ) ) ;
471+ this . allRules . set ( rule . name , ruleMethod ) ;
460472 if ( rule . entry ) {
461473 this . mainRule = ruleMethod ;
462474 }
0 commit comments