1/* 2 * [The "BSD license"] 3 * Copyright (c) 2011 Terence Parr 4 * All rights reserved. 5 * 6 * Conversion to C#: 7 * Copyright (c) 2011 Sam Harwell, Pixel Mine, Inc. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33csharpVisibilityMap ::= [ 34 "private":"private", 35 "protected":"protected", 36 "public":"public", 37 "fragment":"private", 38 default:"private" 39] 40 41/** The overall file structure of a recognizer; stores methods for rules 42 * and cyclic DFAs plus support code. 43 */ 44outputFile( LEXER,PARSER,TREE_PARSER, actionScope, actions, 45 docComment, recognizer, 46 name, tokens, tokenNames, rules, cyclicDFAs, 47 bitsets, buildTemplate, buildAST, rewriteMode, profile, 48 backtracking, synpreds, memoize, numRules, 49 fileName, ANTLRVersion, generatedTimestamp, trace, 50 scopes, superClass, literals) ::= 51<< 52//------------------------------------------------------------------------------ 53// \<auto-generated> 54// This code was generated by a tool. 55// ANTLR Version: <ANTLRVersion> 56// 57// Changes to this file may cause incorrect behavior and will be lost if 58// the code is regenerated. 59// \</auto-generated> 60//------------------------------------------------------------------------------ 61 62// $ANTLR <ANTLRVersion> <fileName> <generatedTimestamp> 63 64// The variable 'variable' is assigned but its value is never used. 65#pragma warning disable 219 66// Unreachable code detected. 67#pragma warning disable 162 68// Missing XML comment for publicly visible type or member 'Type_or_Member' 69#pragma warning disable 1591 70// CLS compliance checking will not be performed on 'type' because it is not visible from outside this assembly. 71#pragma warning disable 3019 72 73<actions.(actionScope).header> 74 75<@imports> 76using System.Collections.Generic; 77using Antlr.Runtime; 78using Antlr.Runtime.Misc; 79<if(TREE_PARSER)> 80using Antlr.Runtime.Tree; 81using RewriteRuleITokenStream = Antlr.Runtime.Tree.RewriteRuleTokenStream; 82<endif> 83<@end> 84<if(actions.(actionScope).namespace)> 85namespace <actions.(actionScope).namespace> 86{ 87<endif> 88<docComment> 89<recognizer> 90<if(actions.(actionScope).namespace)> 91 92} // namespace <actions.(actionScope).namespace> 93<endif> 94>> 95 96lexerInputStreamType() ::= << 97<actions.(actionScope).inputStreamType; null="ICharStream"> 98>> 99 100lexer(grammar, name, tokens, scopes, rules, numRules, filterMode, labelType="CommonToken", 101 superClass={<if(actions.(actionScope).superClass)><actions.(actionScope).superClass><else>Antlr.Runtime.Lexer<endif>}, 102 rewriteElementType={}, ASTLabelType={}) ::= << 103[System.CodeDom.Compiler.GeneratedCode("ANTLR", "<ANTLRVersion>")] 104[System.CLSCompliant(false)] 105<parserModifier(grammar=grammar, actions=actions)> partial class <grammar.recognizerName> : <@superClassName><superClass><@end> 106{ 107 <tokens:{it|public const int <it.name; format="id">=<it.type>;}; separator="\n"> 108 <scopes:{it|<if(it.isDynamicGlobalScope)><globalAttributeScope(scope=it)><endif>}> 109 <actions.lexer.members> 110 111 // delegates 112 <grammar.delegates: 113 {g|private <g.recognizerName> <g:delegateName()>;}; separator="\n"> 114 // delegators 115 <grammar.delegators: 116 {g|private <g.recognizerName> <g:delegateName()>;}; separator="\n"> 117 <last(grammar.delegators):{g|private <g.recognizerName> gParent;}> 118 119 <actions.(actionScope).ctorModifier; null="public"> <grammar.recognizerName>()<! needed by subclasses !> 120 { 121 OnCreated(); 122 } 123 124 <actions.(actionScope).ctorModifier; null="public"> <grammar.recognizerName>(<lexerInputStreamType()> input<grammar.delegators:{g|, <g.recognizerName> <g:delegateName()>}> ) 125 : this(input, new RecognizerSharedState()<grammar.delegators:{g|, <g:delegateName()>}>) 126 { 127 } 128 129 <actions.(actionScope).ctorModifier; null="public"> <grammar.recognizerName>(<lexerInputStreamType()> input, RecognizerSharedState state<grammar.delegators:{g|, <g.recognizerName> <g:delegateName()>}>) 130 : base(input, state) 131 { 132<if(memoize)> 133<if(grammar.grammarIsRoot)> 134 state.ruleMemo = new System.Collections.Generic.Dictionary\<int, int>[<numRules>+1];<\n><! index from 1..n !> 135<endif> 136<endif> 137 <grammar.directDelegates: 138 {g|<g:delegateName()> = new <g.recognizerName>(input, this.state<trunc(g.delegators):{p|, <p:delegateName()>}>, this);}; separator="\n"> 139 <grammar.delegators: 140 {g|this.<g:delegateName()> = <g:delegateName()>;}; separator="\n"> 141 <last(grammar.delegators):{g|gParent = <g:delegateName()>;}> 142 143 OnCreated(); 144 } 145 public override string GrammarFileName { get { return "<fileName>"; } } 146 147<if(grammar.hasDelegates)> 148 public override <lexerInputStreamType()> CharStream 149 { 150 get 151 { 152 return base.CharStream; 153 } 154 set 155 { 156 base.CharStream = value; 157 <grammar.directDelegates: 158 {g|<g:delegateName()> = new <g.recognizerName>(input, state<trunc(g.delegators):{p|, <p:delegateName()>}>, this);}; separator="\n"> 159 <grammar.delegators: 160 {g|this.<g:delegateName()> = <g:delegateName()>;}; separator="\n"> 161 <last(grammar.delegators):{g|gParent = <g:delegateName()>;}> 162 } 163 } 164 165<endif> 166<if(filterMode)> 167 <filteringNextToken()> 168<endif> 169 170 171 partial void OnCreated(); 172 partial void EnterRule(string ruleName, int ruleIndex); 173 partial void LeaveRule(string ruleName, int ruleIndex); 174 175 <rules; separator="\n"> 176 177 <insertLexerSynpreds(synpreds)> 178 179 #region DFA 180 <cyclicDFAs:{dfa | DFA<dfa.decisionNumber> dfa<dfa.decisionNumber>;}; separator="\n"> 181 182 protected override void InitDFAs() 183 { 184 base.InitDFAs(); 185 <cyclicDFAs:{dfa | dfa<dfa.decisionNumber> = new DFA<dfa.decisionNumber>(this<if(dfa.specialStateSTs)>, SpecialStateTransition<dfa.decisionNumber><endif>);}; separator="\n"> 186 } 187 188 <cyclicDFAs:cyclicDFA()> <! dump tables for all DFA !> 189 #endregion 190 191} 192>> 193 194/** A override of Lexer.nextToken() that backtracks over mTokens() looking 195 * for matches. No error can be generated upon error; just rewind, consume 196 * a token and then try again. backtracking needs to be set as well. 197 * Make rule memoization happen only at levels above 1 as we start mTokens 198 * at backtracking==1. 199 */ 200filteringNextToken() ::= << 201public override IToken NextToken() 202{ 203 while (true) 204 { 205 if (input.LA(1) == CharStreamConstants.EndOfFile) 206 { 207 IToken eof = new CommonToken((ICharStream)input, CharStreamConstants.EndOfFile, TokenChannels.Default, input.Index, input.Index); 208 eof.Line = Line; 209 eof.CharPositionInLine = CharPositionInLine; 210 return eof; 211 } 212 state.token = null; 213 state.channel = TokenChannels.Default; 214 state.tokenStartCharIndex = input.Index; 215 state.tokenStartCharPositionInLine = input.CharPositionInLine; 216 state.tokenStartLine = input.Line; 217 state.text = null; 218 try 219 { 220 int m = input.Mark(); 221 state.backtracking=1;<! means we won't throw slow exception !> 222 state.failed=false; 223 mTokens(); 224 state.backtracking=0; 225 <! mTokens backtracks with synpred at backtracking==2 226 and we set the synpredgate to allow actions at level 1. !> 227 if (state.failed) 228 { 229 input.Rewind(m); 230 input.Consume();<! advance one char and try again !> 231 } 232 else 233 { 234 Emit(); 235 return state.token; 236 } 237 } 238 catch (RecognitionException re) 239 { 240 // shouldn't happen in backtracking mode, but... 241 ReportError(re); 242 Recover(re); 243 } 244 } 245} 246 247public override void Memoize(IIntStream input, int ruleIndex, int ruleStartIndex) 248{ 249 if (state.backtracking > 1) 250 base.Memoize(input, ruleIndex, ruleStartIndex); 251} 252 253public override bool AlreadyParsedRule(IIntStream input, int ruleIndex) 254{ 255 if (state.backtracking > 1) 256 return base.AlreadyParsedRule(input, ruleIndex); 257 258 return false; 259} 260>> 261 262actionGate() ::= "state.backtracking == 0" 263 264filteringActionGate() ::= "state.backtracking == 1" 265 266/** How to generate a parser */ 267genericParser(grammar, name, scopes, tokens, tokenNames, rules, numRules, 268 bitsets, inputStreamType, superClass, 269 labelType, members, rewriteElementType, 270 filterMode, ASTLabelType="object") ::= << 271[System.CodeDom.Compiler.GeneratedCode("ANTLR", "<ANTLRVersion>")] 272[System.CLSCompliant(false)] 273<parserModifier(grammar=grammar, actions=actions)> partial class <grammar.recognizerName> : <@superClassName><superClass><@end> 274{ 275<if(grammar.grammarIsRoot)> 276 internal static readonly string[] tokenNames = new string[] { 277 "\<invalid>", "\<EOR>", "\<DOWN>", "\<UP>", <tokenNames; separator=", "> 278 }; 279<endif> 280 <tokens:{it|public const int <it.name; format="id">=<it.type>;}; separator="\n"> 281 282<if(grammar.delegates)> 283 // delegates 284 <grammar.delegates: 285 {g|private <g.recognizerName> <g:delegateName()>;}; separator="\n"> 286<endif> 287<if(grammar.delegators)> 288 // delegators 289 <grammar.delegators: 290 {g|private <g.recognizerName> <g:delegateName()>;}; separator="\n"> 291 <last(grammar.delegators):{g|private <g.recognizerName> gParent;}> 292<endif> 293 294 <scopes:{it|<if(it.isDynamicGlobalScope)><globalAttributeScope(scope=it)><endif>}> 295 <@members()> 296 297 public override string[] TokenNames { get { return <grammar.composite.rootGrammar.recognizerName>.tokenNames; } } 298 public override string GrammarFileName { get { return "<fileName>"; } } 299 300 <members> 301 302 partial void OnCreated(); 303 partial void EnterRule(string ruleName, int ruleIndex); 304 partial void LeaveRule(string ruleName, int ruleIndex); 305 306 #region Rules 307 <rules; separator="\n"> 308 #endregion Rules 309 310<if(grammar.delegatedRules)> 311<! generate rule/method definitions for imported rules so they 312 appear to be defined in this recognizer. !> 313 #region Delegated rules 314<grammar.delegatedRules:{ruleDescriptor| 315 <ruleModifier(grammar=grammar,ruleDescriptor=ruleDescriptor)> <returnType(ruleDescriptor)> <ruleDescriptor.name; format="id">(<ruleDescriptor.parameterScope:parameterScope()>) <!throws RecognitionException !>{ <if(ruleDescriptor.hasReturnValue)>return <endif><ruleDescriptor.grammar:delegateName()>.<ruleDescriptor.name; format="id">(<ruleDescriptor.parameterScope.attributes:{a|<a.name; format="id">}; separator=", ">); \}}; separator="\n"> 316 #endregion Delegated rules 317<endif> 318 319 <insertSynpreds(synpreds)> 320 321<if(cyclicDFAs)> 322 #region DFA 323 <cyclicDFAs:{dfa | private DFA<dfa.decisionNumber> dfa<dfa.decisionNumber>;}; separator="\n"> 324 325 protected override void InitDFAs() 326 { 327 base.InitDFAs(); 328 <cyclicDFAs:{dfa | dfa<dfa.decisionNumber> = new DFA<dfa.decisionNumber>( this<if(dfa.specialStateSTs)>, SpecialStateTransition<dfa.decisionNumber><endif> );}; separator="\n"> 329 } 330 331 <cyclicDFAs:cyclicDFA()><! dump tables for all DFA !> 332 #endregion DFA 333<endif> 334 335<if(bitsets)> 336 #region Follow sets 337 private static class Follow 338 { 339 <bitsets:{it|<bitset(name={_<it.name>_in_<it.inName><it.tokenIndex>}, words64=it.bits)>}; separator="\n"> 340 } 341 #endregion Follow sets 342<endif> 343} 344>> 345 346@genericParser.members() ::= << 347<! WARNING. bug in ST: this is cut-n-paste into Dbg.stg !> 348<actions.(actionScope).ctorModifier; null="public"> <grammar.recognizerName>(<inputStreamType> input<grammar.delegators:{g|, <g.recognizerName> <g:delegateName()>}>) 349 : this(input, new RecognizerSharedState()<grammar.delegators:{g|, <g:delegateName()>}>) 350{ 351} 352<actions.(actionScope).ctorModifier; null="public"> <grammar.recognizerName>(<inputStreamType> input, RecognizerSharedState state<grammar.delegators:{g|, <g.recognizerName> <g:delegateName()>}>) 353 : base(input, state) 354{ 355 <parserCtorBody()> 356<if(grammar.directDelegates)> 357 <grammar.directDelegates: 358 {g|<g:delegateName()> = new <g.recognizerName>(input, state<trunc(g.delegators):{p|, <p:delegateName()>}>, this);}; separator="\n"> 359<endif> 360<if(grammar.indirectDelegates)> 361 <grammar.indirectDelegates:{g | <g:delegateName()> = <g.delegator:delegateName()>.<g:delegateName()>;}; separator="\n"> 362<endif> 363<if(grammar.delegators)> 364 <last(grammar.delegators):{g|gParent = <g:delegateName()>;}> 365<endif> 366 OnCreated(); 367} 368>> 369 370// imported grammars are 'public' (can't be internal because their return scope classes must be accessible) 371parserModifier(grammar, actions) ::= << 372<if(grammar.grammarIsRoot)><actions.(actionScope).modifier; null="public"><else>public<endif> 373>> 374 375parserCtorBody() ::= << 376<if(memoize)> 377<if(grammar.grammarIsRoot)> 378this.state.ruleMemo = new System.Collections.Generic.Dictionary\<int, int>[<length(grammar.allImportedRules)>+1];<\n><! index from 1..n !> 379<endif> 380<endif> 381<grammar.delegators: 382 {g|this.<g:delegateName()> = <g:delegateName()>;}; separator="\n"> 383>> 384 385parser(grammar, name, scopes, tokens, tokenNames, rules, numRules, bitsets, 386 ASTLabelType="object", superClass={<if(actions.(actionScope).superClass)><actions.(actionScope).superClass><else>Antlr.Runtime.Parser<endif>}, labelType="IToken", 387 members={<actions.parser.members>}) ::= << 388<genericParser(inputStreamType="ITokenStream", rewriteElementType="IToken", filterMode=false, ...)> 389>> 390 391/** How to generate a tree parser; same as parser except the input 392 * stream is a different type. 393 */ 394treeParser(grammar, name, scopes, tokens, tokenNames, globalAction, rules, 395 numRules, bitsets, filterMode, labelType={<ASTLabelType>}, ASTLabelType="object", 396 superClass={<if(actions.(actionScope).superClass)><actions.(actionScope).superClass><else>Antlr.Runtime.Tree.<if(filterMode)><if(buildAST)>TreeRewriter<else>TreeFilter<endif><else>TreeParser<endif><endif>}, 397 members={<actions.treeparser.members>}) ::= << 398<genericParser(inputStreamType="ITreeNodeStream", rewriteElementType="Node", ...)> 399>> 400 401/** A simpler version of a rule template that is specific to the imaginary 402 * rules created for syntactic predicates. As they never have return values 403 * nor parameters etc..., just give simplest possible method. Don't do 404 * any of the normal memoization stuff in here either; it's a waste. 405 * As predicates cannot be inlined into the invoking rule, they need to 406 * be in a rule by themselves. 407 */ 408synpredRule(ruleName, ruleDescriptor, block, description, nakedBlock) ::= 409<< 410 411partial void EnterRule_<ruleName>_fragment(); 412partial void LeaveRule_<ruleName>_fragment(); 413 414// $ANTLR start <ruleName> 415public <!final !>void <ruleName>_fragment(<ruleDescriptor.parameterScope:parameterScope()>) 416{ 417 <ruleLabelDefs(...)> 418 EnterRule_<ruleName>_fragment(); 419 EnterRule("<ruleName>_fragment", <ruleDescriptor.index>); 420 TraceIn("<ruleName>_fragment", <ruleDescriptor.index>); 421 try 422 { 423 <block> 424 } 425 finally 426 { 427 TraceOut("<ruleName>_fragment", <ruleDescriptor.index>); 428 LeaveRule("<ruleName>_fragment", <ruleDescriptor.index>); 429 LeaveRule_<ruleName>_fragment(); 430 } 431} 432// $ANTLR end <ruleName> 433>> 434 435insertLexerSynpreds(synpreds) ::= << 436<insertSynpreds(synpreds)> 437>> 438 439insertSynpreds(synpreds) ::= << 440<if(synpreds)> 441#region Synpreds 442private bool EvaluatePredicate(System.Action fragment) 443{ 444 bool success = false; 445 state.backtracking++; 446 <@start()> 447 try { DebugBeginBacktrack(state.backtracking); 448 int start = input.Mark(); 449 try 450 { 451 fragment(); 452 } 453 catch ( RecognitionException re ) 454 { 455 System.Console.Error.WriteLine("impossible: "+re); 456 } 457 success = !state.failed; 458 input.Rewind(start); 459 } finally { DebugEndBacktrack(state.backtracking, success); } 460 <@stop()> 461 state.backtracking--; 462 state.failed=false; 463 return success; 464} 465#endregion Synpreds 466<endif> 467>> 468 469ruleMemoization(name) ::= << 470<if(memoize)> 471if (state.backtracking > 0 && AlreadyParsedRule(input, <ruleDescriptor.index>)) { <returnFromRule()> } 472<endif> 473>> 474 475/** How to test for failure and return from rule */ 476checkRuleBacktrackFailure() ::= << 477<if(backtracking)>if (state.failed) <returnFromRule()><endif> 478>> 479 480/** This rule has failed, exit indicating failure during backtrack */ 481ruleBacktrackFailure() ::= << 482<if(backtracking)>if (state.backtracking>0) {state.failed=true; <returnFromRule()>}<endif> 483>> 484 485/** How to generate code for a rule. This includes any return type 486 * data aggregates required for multiple return values. 487 */ 488rule(ruleName,ruleDescriptor,block,emptyRule,description,exceptions,finally,memoize) ::= << 489<ruleAttributeScope(scope=ruleDescriptor.ruleScope)> 490<returnScope(ruleDescriptor.returnScope)> 491partial void EnterRule_<ruleName>(); 492partial void LeaveRule_<ruleName>(); 493 494// $ANTLR start "<ruleName>" 495// <fileName>:<description> 496[GrammarRule("<ruleName>")] 497<ruleModifier(grammar=grammar,ruleDescriptor=ruleDescriptor)> <returnType(ruleDescriptor)> <ruleName; format="id">(<ruleDescriptor.parameterScope:parameterScope()>) 498{ 499 EnterRule_<ruleName>(); 500 EnterRule("<ruleName>", <ruleDescriptor.index>); 501 TraceIn("<ruleName>", <ruleDescriptor.index>); 502 <ruleScopeSetUp()> 503 <ruleDeclarations()> 504 <ruleLabelDefs(...)> 505 <ruleDescriptor.actions.init> 506 try { DebugEnterRule(GrammarFileName, "<ruleName>"); 507 DebugLocation(<ruleDescriptor.tree.line>, <ruleDescriptor.EORNode.charPositionInLine>); 508 <@preamble()> 509 try 510 { 511 <ruleMemoization(name=ruleName)> 512 <block> 513 <ruleCleanUp()> 514 <(ruleDescriptor.actions.after):execAction()> 515 } 516<if(exceptions)> 517 <exceptions:{e|<catch(decl=e.decl,action=e.action)><\n>}> 518<else> 519<if(!emptyRule)> 520<if(actions.(actionScope).rulecatch)> 521 <actions.(actionScope).rulecatch> 522<else> 523 catch (RecognitionException re) 524 { 525 ReportError(re); 526 Recover(input,re); 527 <@setErrorReturnValue()> 528 } 529<endif> 530<endif> 531<endif> 532 finally 533 { 534 TraceOut("<ruleName>", <ruleDescriptor.index>); 535 LeaveRule("<ruleName>", <ruleDescriptor.index>); 536 LeaveRule_<ruleName>(); 537 <memoize()> 538 <ruleScopeCleanUp()> 539 <finally> 540 } 541 DebugLocation(<ruleDescriptor.EORNode.line>, <ruleDescriptor.EORNode.charPositionInLine>); 542 } finally { DebugExitRule(GrammarFileName, "<ruleName>"); } 543 <@postamble()> 544 <returnFromRule()><\n> 545} 546// $ANTLR end "<ruleName>" 547>> 548 549// imported grammars need to have internal rules 550ruleModifier(grammar,ruleDescriptor) ::= << 551<if(grammar.grammarIsRoot)><csharpVisibilityMap.(ruleDescriptor.modifier); null="private"><else>internal<endif> 552>> 553 554// imported grammars need to have public return scopes 555returnScopeModifier(grammar,ruleDescriptor) ::= << 556<if(grammar.grammarIsRoot)><csharpVisibilityMap.(ruleDescriptor.modifier); null="private"><else>public<endif> 557>> 558 559catch(decl,action) ::= << 560catch (<e.decl>) 561{ 562 <e.action> 563} 564>> 565 566ruleDeclarations() ::= << 567<if(ruleDescriptor.hasMultipleReturnValues)> 568<returnType(ruleDescriptor)> retval = new <returnType(ruleDescriptor)>(<if(ruleDescriptor.returnScope.attributes)>this<endif>); 569retval.Start = (<labelType>)input.LT(1); 570<else> 571<ruleDescriptor.returnScope.attributes:{ a | 572<a.type> <a.name; format="id"> = <if(a.initValue)><a.initValue><else><initValue(a.type)><endif>; 573}> 574<endif> 575<if(memoize)> 576int <ruleDescriptor.name>_StartIndex = input.Index; 577<endif> 578>> 579 580ruleScopeSetUp() ::= << 581<ruleDescriptor.useScopes:{it|<it>_stack.Push(new <it>_scope(this));<it>_scopeInit(<it>_stack.Peek());}; separator="\n"> 582<ruleDescriptor.ruleScope:{it|<it.name>_stack.Push(new <it.name>_scope(this));<it.name>_scopeInit(<it.name>_stack.Peek());}; separator="\n"> 583>> 584 585ruleScopeCleanUp() ::= << 586<ruleDescriptor.useScopes:{it|<it>_scopeAfter(<it>_stack.Peek());<it>_stack.Pop();}; separator="\n"> 587<ruleDescriptor.ruleScope:{it|<it.name>_scopeAfter(<it.name>_stack.Peek());<it.name>_stack.Pop();}; separator="\n"> 588>> 589 590ruleLabelDefs(ruleDescriptor, labelType, ASTLabelType, rewriteElementType) ::= << 591<[ruleDescriptor.tokenLabels,ruleDescriptor.tokenListLabels,ruleDescriptor.wildcardTreeLabels,ruleDescriptor.wildcardTreeListLabels] 592 :{it|<labelType> <it.label.text> = default(<labelType>);}; separator="\n" 593> 594<ruleDescriptor.tokenListLabels 595 :{it|List\<<labelType>\> list_<it.label.text> = null;}; separator="\n" 596> 597<[ruleDescriptor.ruleListLabels,ruleDescriptor.wildcardTreeListLabels] 598 :{it|List\<<ASTLabelType>\> list_<it.label.text> = null;}; separator="\n" 599> 600<ruleDescriptor.ruleLabels:ruleLabelDef(); separator="\n"> 601<ruleDescriptor.ruleListLabels:ruleLabelDef(); separator="\n"> 602>> 603 604lexerRuleLabelDefs() ::= << 605<[ruleDescriptor.tokenLabels, 606 ruleDescriptor.tokenListLabels, 607 ruleDescriptor.ruleLabels] 608 :{it|<labelType> <it.label.text> = default(<labelType>);}; separator="\n" 609> 610<[ruleDescriptor.charListLabels, 611 ruleDescriptor.charLabels] 612 :{it|int <it.label.text> = 0;}; separator="\n" 613> 614<[ruleDescriptor.tokenListLabels, 615 ruleDescriptor.ruleListLabels] 616 :{it|List\<<labelType>\> list_<it.label.text> = null;}; separator="\n" 617> 618<ruleDescriptor.charListLabels:{it|List\<int\> list_<it.label.text> = null;}; separator="\n" 619> 620>> 621 622returnFromRule() ::= <% 623return 624<if(!ruleDescriptor.isSynPred)> 625<if(ruleDescriptor.hasReturnValue)> 626<if(ruleDescriptor.hasSingleReturnValue)> 627<! This comment is a hack to make sure the following 628 single space appears in the output. !> <ruleDescriptor.singleValueReturnName> 629<else> 630<!!> retval 631<endif> 632<endif> 633<endif> 634; 635%> 636 637ruleCleanUp() ::= << 638<if(ruleDescriptor.hasMultipleReturnValues)> 639<if(!TREE_PARSER)> 640retval.Stop = (<labelType>)input.LT(-1); 641<endif> 642<endif> 643>> 644 645memoize() ::= << 646<if(memoize)> 647<if(backtracking)> 648if (state.backtracking > 0) { Memoize(input, <ruleDescriptor.index>, <ruleDescriptor.name>_StartIndex); } 649<endif> 650<endif> 651>> 652 653/** How to generate a rule in the lexer; naked blocks are used for 654 * fragment rules. 655 */ 656lexerRule(ruleName,nakedBlock,ruleDescriptor,block,memoize) ::= << 657 658partial void EnterRule_<ruleName>(); 659partial void LeaveRule_<ruleName>(); 660 661// $ANTLR start "<ruleName>" 662[GrammarRule("<ruleName>")] 663<ruleModifier(grammar=grammar,ruleDescriptor=ruleDescriptor)> void m<ruleName>(<ruleDescriptor.parameterScope:parameterScope()>) 664{ 665 EnterRule_<ruleName>(); 666 EnterRule("<ruleName>", <ruleDescriptor.index>); 667 TraceIn("<ruleName>", <ruleDescriptor.index>); 668 <ruleScopeSetUp()> 669 <ruleDeclarations()> 670 try 671 { 672<if(nakedBlock)> 673 <ruleMemoization(name=ruleName)> 674 <lexerRuleLabelDefs()> 675 <ruleDescriptor.actions.init> 676 <block> 677<else> 678 int _type = <ruleName>; 679 int _channel = DefaultTokenChannel; 680 <ruleMemoization(name=ruleName)> 681 <lexerRuleLabelDefs()> 682 <ruleDescriptor.actions.init> 683 <block> 684 <ruleCleanUp()> 685 state.type = _type; 686 state.channel = _channel; 687 <(ruleDescriptor.actions.after):execAction()> 688<endif> 689 } 690 finally 691 { 692 TraceOut("<ruleName>", <ruleDescriptor.index>); 693 LeaveRule("<ruleName>", <ruleDescriptor.index>); 694 LeaveRule_<ruleName>(); 695 <ruleScopeCleanUp()> 696 <memoize()> 697 } 698} 699// $ANTLR end "<ruleName>" 700>> 701 702/** How to generate code for the implicitly-defined lexer grammar rule 703 * that chooses between lexer rules. 704 */ 705tokensRule(ruleName,nakedBlock,args,block,ruleDescriptor) ::= << 706 707public override void mTokens() 708{ 709 <block><\n> 710} 711>> 712 713// S U B R U L E S 714 715/** A (...) subrule with multiple alternatives */ 716block(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= << 717// <fileName>:<description> 718int alt<decisionNumber>=<maxAlt>; 719<decls> 720<@predecision()> 721try { DebugEnterSubRule(<decisionNumber>); 722try { DebugEnterDecision(<decisionNumber>, false<!<decision.dfa.hasSynPred>!>); 723<decision> 724} finally { DebugExitDecision(<decisionNumber>); } 725<@postdecision()> 726<@prebranch()> 727switch (alt<decisionNumber>) 728{ 729<alts:{a|<altSwitchCase(i,a)>}> 730} 731} finally { DebugExitSubRule(<decisionNumber>); } 732<@postbranch()> 733>> 734 735/** A rule block with multiple alternatives */ 736ruleBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= << 737// <fileName>:<description> 738int alt<decisionNumber>=<maxAlt>; 739<decls> 740<@predecision()> 741try { DebugEnterDecision(<decisionNumber>, false<!<decision.dfa.hasSynPred>!>); 742<decision> 743} finally { DebugExitDecision(<decisionNumber>); } 744<@postdecision()> 745switch (alt<decisionNumber>) 746{ 747<alts:{a|<altSwitchCase(i,a)>}> 748} 749>> 750 751ruleBlockSingleAlt(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,description) ::= << 752// <fileName>:<description> 753<decls> 754<@prealt()> 755DebugEnterAlt(1); 756<alts> 757<@postalt()> 758>> 759 760/** A special case of a (...) subrule with a single alternative */ 761blockSingleAlt(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,description) ::= << 762// <fileName>:<description> 763<decls> 764<@prealt()> 765DebugEnterAlt(1); 766<alts> 767<@postalt()> 768>> 769 770/** A (..)+ block with 1 or more alternatives */ 771positiveClosureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= << 772// <fileName>:<description> 773int cnt<decisionNumber>=0; 774<decls> 775<@preloop()> 776try { DebugEnterSubRule(<decisionNumber>); 777while (true) 778{ 779 int alt<decisionNumber>=<maxAlt>; 780 <@predecision()> 781 try { DebugEnterDecision(<decisionNumber>, false<!<decision.dfa.hasSynPred>!>); 782 <decision> 783 } finally { DebugExitDecision(<decisionNumber>); } 784 <@postdecision()> 785 switch (alt<decisionNumber>) 786 { 787 <alts:{a|<altSwitchCase(i,a)>}> 788 default: 789 if (cnt<decisionNumber> >= 1) 790 goto loop<decisionNumber>; 791 792 <ruleBacktrackFailure()> 793 EarlyExitException eee<decisionNumber> = new EarlyExitException( <decisionNumber>, input ); 794 DebugRecognitionException(eee<decisionNumber>); 795 <@earlyExitException()> 796 throw eee<decisionNumber>; 797 } 798 cnt<decisionNumber>++; 799} 800loop<decisionNumber>: 801 ; 802 803} finally { DebugExitSubRule(<decisionNumber>); } 804<@postloop()> 805>> 806 807positiveClosureBlockSingleAlt ::= positiveClosureBlock 808 809/** A (..)* block with 1 or more alternatives */ 810closureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= << 811// <fileName>:<description> 812<decls> 813<@preloop()> 814try { DebugEnterSubRule(<decisionNumber>); 815while (true) 816{ 817 int alt<decisionNumber>=<maxAlt>; 818 <@predecision()> 819 try { DebugEnterDecision(<decisionNumber>, false<!<decision.dfa.hasSynPred>!>); 820 <decision> 821 } finally { DebugExitDecision(<decisionNumber>); } 822 <@postdecision()> 823 switch ( alt<decisionNumber> ) 824 { 825 <alts:{a|<altSwitchCase(i,a)>}> 826 default: 827 goto loop<decisionNumber>; 828 } 829} 830 831loop<decisionNumber>: 832 ; 833 834} finally { DebugExitSubRule(<decisionNumber>); } 835<@postloop()> 836>> 837 838closureBlockSingleAlt ::= closureBlock 839 840/** Optional blocks (x)? are translated to (x|) by before code generation 841 * so we can just use the normal block template 842 */ 843optionalBlock ::= block 844 845optionalBlockSingleAlt ::= block 846 847/** A case in a switch that jumps to an alternative given the alternative 848 * number. A DFA predicts the alternative and then a simple switch 849 * does the jump to the code that actually matches that alternative. 850 */ 851altSwitchCase(altNum,alt) ::= << 852case <altNum>: 853 <@prealt()> 854 DebugEnterAlt(<altNum>); 855 <alt> 856 break;<\n> 857>> 858 859/** An alternative is just a list of elements; at outermost level */ 860alt(elements,altNum,description,autoAST,outerAlt,treeLevel,rew) ::= << 861// <fileName>:<description> 862{ 863<@declarations()> 864<elements:element()> 865<rew> 866<@cleanup()> 867} 868>> 869 870/** What to emit when there is no rewrite. For auto build 871 * mode, does nothing. 872 */ 873noRewrite(rewriteBlockLevel, treeLevel) ::= "" 874 875// E L E M E N T S 876 877/** Dump the elements one per line */ 878element(it) ::= <% 879<@prematch()> 880DebugLocation(<it.line>, <it.pos>);<\n> 881<it.el><\n> 882%> 883 884/** match a token optionally with a label in front */ 885tokenRef(token,label,elementIndex,terminalOptions) ::= << 886<if(label)><label>=(<labelType>)<endif>Match(input,<token>,Follow._<token>_in_<ruleName><elementIndex>); <checkRuleBacktrackFailure()> 887>> 888 889/** ids+=ID */ 890tokenRefAndListLabel(token,label,elementIndex,terminalOptions) ::= << 891<tokenRef(...)> 892<listLabelElem(elem=label,elemType=labelType,...)> 893>> 894 895listLabel(label,elem) ::= << 896#error The listLabel template should not be used with this target.<\n> 897>> 898 899listLabelElem(label,elem,elemType) ::= << 900if (list_<label>==null) list_<label>=new List\<<elemType; null={<labelType>}>\>(); 901list_<label>.Add(<elem>);<\n> 902>> 903 904/** match a character */ 905charRef(char,label) ::= << 906<if(label)> 907<label> = input.LA(1);<\n> 908<endif> 909Match(<char>); <checkRuleBacktrackFailure()> 910>> 911 912/** match a character range */ 913charRangeRef(a,b,label) ::= << 914<if(label)> 915<label> = input.LA(1);<\n> 916<endif> 917MatchRange(<a>,<b>); <checkRuleBacktrackFailure()> 918>> 919 920/** For now, sets are interval tests and must be tested inline */ 921matchSet(s,label,terminalOptions,elementIndex,postmatchCode="") ::= << 922<if(label)> 923<matchSetLabel()> 924<endif> 925if (<s>) 926{ 927 input.Consume(); 928 <postmatchCode> 929 <if(!LEXER)>state.errorRecovery=false;<endif><if(backtracking)>state.failed=false;<endif> 930} 931else 932{ 933 <ruleBacktrackFailure()> 934 MismatchedSetException mse = new MismatchedSetException(null,input); 935 DebugRecognitionException(mse); 936 <@mismatchedSetException()> 937<if(LEXER)> 938 Recover(mse); 939 throw mse; 940<else> 941 throw mse; 942 <! use following code to make it recover inline; remove throw mse; 943 recoverFromMismatchedSet(input,mse,Follow._set_in_<ruleName><elementIndex>); 944 !> 945<endif> 946}<\n> 947>> 948 949matchSetUnchecked(s,label,elementIndex,postmatchCode=false) ::= <% 950<if(label)> 951<matchSetLabel()><\n> 952<endif> 953input.Consume();<\n> 954<if(postmatchCode)> 955<postmatchCode><\n> 956<endif> 957<if(!LEXER)>state.errorRecovery=false;<endif><if(backtracking)>state.failed=false;<endif> 958%> 959 960matchSetLabel() ::= <% 961<if(LEXER)> 962<label>= input.LA(1); 963<else> 964<label>=(<labelType>)input.LT(1); 965<endif> 966%> 967 968matchRuleBlockSet ::= matchSet 969 970matchSetAndListLabel(s,label,elementIndex,postmatchCode) ::= << 971<matchSet(...)> 972<listLabelElem(elem=label,elemType=labelType,...)> 973>> 974 975/** Match a string literal */ 976lexerStringRef(string,label,elementIndex) ::= <% 977<if(label)> 978int <label>Start = CharIndex;<\n> 979Match(<string>); <checkRuleBacktrackFailure()><\n> 980int <label>StartLine<elementIndex> = Line;<\n> 981int <label>StartCharPos<elementIndex> = CharPositionInLine;<\n> 982<label> = new <labelType>(input, TokenTypes.Invalid, TokenChannels.Default, <label>Start, CharIndex-1);<\n> 983<label>.Line = <label>StartLine<elementIndex>;<\n> 984<label>.CharPositionInLine = <label>StartCharPos<elementIndex>; 985<else> 986Match(<string>); <checkRuleBacktrackFailure()><\n> 987<endif> 988%> 989 990wildcard(token,label,elementIndex,terminalOptions) ::= << 991<if(label)> 992<label>=(<labelType>)input.LT(1);<\n> 993<endif> 994MatchAny(input); <checkRuleBacktrackFailure()> 995>> 996 997wildcardAndListLabel(token,label,elementIndex,terminalOptions) ::= << 998<wildcard(...)> 999<listLabelElem(elem=label,elemType=labelType,...)> 1000>> 1001 1002/** Match . wildcard in lexer */ 1003wildcardChar(label, elementIndex) ::= << 1004<if(label)> 1005<label> = input.LA(1);<\n> 1006<endif> 1007MatchAny(); <checkRuleBacktrackFailure()> 1008>> 1009 1010wildcardCharListLabel(label, elementIndex) ::= << 1011<wildcardChar(...)> 1012<listLabelElem(elem=label,elemType=labelType,...)> 1013>> 1014 1015/** Match a rule reference by invoking it possibly with arguments 1016 * and a return value or values. The 'rule' argument was the 1017 * target rule name, but now is type Rule, whose toString is 1018 * same: the rule name. Now though you can access full rule 1019 * descriptor stuff. 1020 */ 1021ruleRef(rule,label,elementIndex,args,scope) ::= << 1022PushFollow(Follow._<rule.name>_in_<ruleName><elementIndex>); 1023<if(label)><label>=<endif><if(scope)><scope:delegateName()>.<endif><rule.name; format="id">(<args; separator=", ">); 1024PopFollow(); 1025<checkRuleBacktrackFailure()> 1026>> 1027 1028/** ids+=r */ 1029ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= << 1030<ruleRef(...)> 1031<listLabelElem(elem=label,elemType={<ASTLabelType>},...)> 1032>> 1033 1034/** A lexer rule reference. 1035 * 1036 * The 'rule' argument was the target rule name, but now 1037 * is type Rule, whose toString is same: the rule name. 1038 * Now though you can access full rule descriptor stuff. 1039 */ 1040lexerRuleRef(rule,label,args,elementIndex,scope) ::= <% 1041<if(label)> 1042int <label>Start<elementIndex> = CharIndex;<\n> 1043int <label>StartLine<elementIndex> = Line;<\n> 1044int <label>StartCharPos<elementIndex> = CharPositionInLine;<\n> 1045<if(scope)><scope:delegateName()>.<endif>m<rule.name>(<args; separator=", ">); <checkRuleBacktrackFailure()><\n> 1046<label> = new <labelType>(input, TokenTypes.Invalid, TokenChannels.Default, <label>Start<elementIndex>, CharIndex-1);<\n> 1047<label>.Line = <label>StartLine<elementIndex>;<\n> 1048<label>.CharPositionInLine = <label>StartCharPos<elementIndex>; 1049<else> 1050<if(scope)><scope:delegateName()>.<endif>m<rule.name>(<args; separator=", ">); <checkRuleBacktrackFailure()> 1051<endif> 1052%> 1053 1054/** i+=INT in lexer */ 1055lexerRuleRefAndListLabel(rule,label,args,elementIndex,scope) ::= << 1056<lexerRuleRef(...)> 1057<listLabelElem(elem=label,elemType=labelType,...)> 1058>> 1059 1060/** EOF in the lexer */ 1061lexerMatchEOF(label,elementIndex) ::= <% 1062<if(label)> 1063int <label>Start<elementIndex> = CharIndex;<\n> 1064int <label>StartLine<elementIndex> = Line;<\n> 1065int <label>StartCharPos<elementIndex> = CharPositionInLine;<\n> 1066Match(EOF); <checkRuleBacktrackFailure()><\n> 1067<labelType> <label> = new <labelType>(input, EOF, TokenChannels.Default, <label>Start<elementIndex>, CharIndex-1);<\n> 1068<label>.Line = <label>StartLine<elementIndex>;<\n> 1069<label>.CharPositionInLine = <label>StartCharPos<elementIndex>; 1070<else> 1071Match(EOF); <checkRuleBacktrackFailure()> 1072<endif> 1073%> 1074 1075// used for left-recursive rules 1076recRuleDefArg() ::= "int <recRuleArg()>" 1077recRuleArg() ::= "_p" 1078recRuleAltPredicate(ruleName,opPrec) ::= "<recRuleArg()> \<= <opPrec>" 1079recRuleSetResultAction() ::= "root_0=$<ruleName>_primary.tree;" 1080 1081/** match ^(root children) in tree parser */ 1082tree(root, actionsAfterRoot, children, nullableChildList, 1083 enclosingTreeLevel, treeLevel) ::= << 1084<root:element()> 1085<actionsAfterRoot:element()> 1086<if(nullableChildList)> 1087if (input.LA(1) == TokenTypes.Down) 1088{ 1089 Match(input, TokenTypes.Down, null); <checkRuleBacktrackFailure()> 1090 <children:element()> 1091 Match(input, TokenTypes.Up, null); <checkRuleBacktrackFailure()> 1092} 1093<else> 1094Match(input, TokenTypes.Down, null); <checkRuleBacktrackFailure()> 1095<children:element()> 1096Match(input, TokenTypes.Up, null); <checkRuleBacktrackFailure()> 1097<endif> 1098>> 1099 1100/** Every predicate is used as a validating predicate (even when it is 1101 * also hoisted into a prediction expression). 1102 */ 1103validateSemanticPredicate(pred,description) ::= << 1104if (!(<evalPredicate(...)>)) 1105{ 1106 <ruleBacktrackFailure()> 1107 throw new FailedPredicateException(input, "<ruleName>", "<description>"); 1108} 1109>> 1110 1111// F i x e d D F A (if-then-else) 1112 1113dfaState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= << 1114int LA<decisionNumber>_<stateNumber> = input.LA(<k>);<\n> 1115<edges; separator="\nelse "> 1116else 1117{ 1118<if(eotPredictsAlt)> 1119 alt<decisionNumber> = <eotPredictsAlt>; 1120<else> 1121 <ruleBacktrackFailure()> 1122 NoViableAltException nvae = new NoViableAltException("<description>", <decisionNumber>, <stateNumber>, input); 1123 DebugRecognitionException(nvae); 1124 <@noViableAltException()> 1125 throw nvae; 1126<endif> 1127} 1128>> 1129 1130/** Same as a normal DFA state except that we don't examine lookahead 1131 * for the bypass alternative. It delays error detection but this 1132 * is faster, smaller, and more what people expect. For (X)? people 1133 * expect "if ( LA(1)==X ) match(X);" and that's it. 1134 */ 1135dfaOptionalBlockState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= << 1136int LA<decisionNumber>_<stateNumber> = input.LA(<k>);<\n> 1137<edges; separator="\nelse "> 1138>> 1139 1140/** A DFA state that is actually the loopback decision of a closure 1141 * loop. If end-of-token (EOT) predicts any of the targets then it 1142 * should act like a default clause (i.e., no error can be generated). 1143 * This is used only in the lexer so that for ('a')* on the end of a rule 1144 * anything other than 'a' predicts exiting. 1145 */ 1146dfaLoopbackState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= << 1147int LA<decisionNumber>_<stateNumber> = input.LA(<k>);<\n> 1148<edges; separator="\nelse "><\n> 1149<if(eotPredictsAlt)> 1150<if(!edges)> 1151alt<decisionNumber> = <eotPredictsAlt>;<! if no edges, don't gen ELSE !> 1152<else> 1153else 1154{ 1155 alt<decisionNumber> = <eotPredictsAlt>; 1156}<\n> 1157<endif> 1158<endif> 1159>> 1160 1161/** An accept state indicates a unique alternative has been predicted */ 1162dfaAcceptState(alt) ::= "alt<decisionNumber> = <alt>;" 1163 1164/** A simple edge with an expression. If the expression is satisfied, 1165 * enter to the target state. To handle gated productions, we may 1166 * have to evaluate some predicates for this edge. 1167 */ 1168dfaEdge(labelExpr, targetState, predicates) ::= << 1169if ((<labelExpr>)<if(predicates)> && (<predicates>)<endif>) 1170{ 1171 <targetState> 1172} 1173>> 1174 1175// F i x e d D F A (switch case) 1176 1177/** A DFA state where a SWITCH may be generated. The code generator 1178 * decides if this is possible: CodeGenerator.canGenerateSwitch(). 1179 */ 1180dfaStateSwitch(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= << 1181switch (input.LA(<k>)) 1182{ 1183<edges; separator="\n"> 1184default: 1185<if(eotPredictsAlt)> 1186 alt<decisionNumber>=<eotPredictsAlt>; 1187 break;<\n> 1188<else> 1189 { 1190 <ruleBacktrackFailure()> 1191 NoViableAltException nvae = new NoViableAltException("<description>", <decisionNumber>, <stateNumber>, input); 1192 DebugRecognitionException(nvae); 1193 <@noViableAltException()> 1194 throw nvae; 1195 } 1196<endif> 1197}<\n> 1198>> 1199 1200dfaOptionalBlockStateSwitch(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= << 1201switch (input.LA(<k>)) 1202{ 1203<edges; separator="\n"> 1204}<\n> 1205>> 1206 1207dfaLoopbackStateSwitch(k, edges,eotPredictsAlt,description,stateNumber,semPredState) ::= << 1208switch (input.LA(<k>)) 1209{ 1210<edges; separator="\n"> 1211<if(eotPredictsAlt)> 1212default: 1213 alt<decisionNumber>=<eotPredictsAlt>; 1214 break;<\n> 1215<endif> 1216}<\n> 1217>> 1218 1219dfaEdgeSwitch(labels, targetState) ::= << 1220<labels:{it|case <it>:}; separator="\n"> 1221 { 1222 <targetState> 1223 } 1224 break; 1225>> 1226 1227// C y c l i c D F A 1228 1229/** The code to initiate execution of a cyclic DFA; this is used 1230 * in the rule to predict an alt just like the fixed DFA case. 1231 * The <name> attribute is inherited via the parser, lexer, ... 1232 */ 1233dfaDecision(decisionNumber,description) ::= << 1234try 1235{ 1236 alt<decisionNumber> = dfa<decisionNumber>.Predict(input); 1237} 1238catch (NoViableAltException nvae) 1239{ 1240 DebugRecognitionException(nvae); 1241 throw; 1242} 1243>> 1244 1245/* Dump DFA tables as run-length-encoded Strings of octal values. 1246 * Can't use hex as compiler translates them before compilation. 1247 * These strings are split into multiple, concatenated strings. 1248 * Java puts them back together at compile time thankfully. 1249 * Java cannot handle large static arrays, so we're stuck with this 1250 * encode/decode approach. See analysis and runtime DFA for 1251 * the encoding methods. 1252 */ 1253cyclicDFA(dfa) ::= << 1254private class DFA<dfa.decisionNumber> : DFA 1255{ 1256 private const string DFA<dfa.decisionNumber>_eotS = 1257 "<dfa.javaCompressedEOT; wrap="\"+\n\t\t\"">"; 1258 private const string DFA<dfa.decisionNumber>_eofS = 1259 "<dfa.javaCompressedEOF; wrap="\"+\n\t\t\"">"; 1260 private const string DFA<dfa.decisionNumber>_minS = 1261 "<dfa.javaCompressedMin; wrap="\"+\n\t\t\"">"; 1262 private const string DFA<dfa.decisionNumber>_maxS = 1263 "<dfa.javaCompressedMax; wrap="\"+\n\t\t\"">"; 1264 private const string DFA<dfa.decisionNumber>_acceptS = 1265 "<dfa.javaCompressedAccept; wrap="\"+\n\t\t\"">"; 1266 private const string DFA<dfa.decisionNumber>_specialS = 1267 "<dfa.javaCompressedSpecial; wrap="\"+\n\t\t\"">}>"; 1268 private static readonly string[] DFA<dfa.decisionNumber>_transitionS = 1269 { 1270 <dfa.javaCompressedTransition:{s|"<s; wrap="\"+\n\"">"}; separator=",\n"> 1271 }; 1272 1273 private static readonly short[] DFA<dfa.decisionNumber>_eot = DFA.UnpackEncodedString(DFA<dfa.decisionNumber>_eotS); 1274 private static readonly short[] DFA<dfa.decisionNumber>_eof = DFA.UnpackEncodedString(DFA<dfa.decisionNumber>_eofS); 1275 private static readonly char[] DFA<dfa.decisionNumber>_min = DFA.UnpackEncodedStringToUnsignedChars(DFA<dfa.decisionNumber>_minS); 1276 private static readonly char[] DFA<dfa.decisionNumber>_max = DFA.UnpackEncodedStringToUnsignedChars(DFA<dfa.decisionNumber>_maxS); 1277 private static readonly short[] DFA<dfa.decisionNumber>_accept = DFA.UnpackEncodedString(DFA<dfa.decisionNumber>_acceptS); 1278 private static readonly short[] DFA<dfa.decisionNumber>_special = DFA.UnpackEncodedString(DFA<dfa.decisionNumber>_specialS); 1279 private static readonly short[][] DFA<dfa.decisionNumber>_transition; 1280 1281 static DFA<dfa.decisionNumber>() 1282 { 1283 int numStates = DFA<dfa.decisionNumber>_transitionS.Length; 1284 DFA<dfa.decisionNumber>_transition = new short[numStates][]; 1285 for ( int i=0; i \< numStates; i++ ) 1286 { 1287 DFA<dfa.decisionNumber>_transition[i] = DFA.UnpackEncodedString(DFA<dfa.decisionNumber>_transitionS[i]); 1288 } 1289 } 1290 1291 public DFA<dfa.decisionNumber>( BaseRecognizer recognizer<if(dfa.specialStateSTs)>, SpecialStateTransitionHandler specialStateTransition<endif> ) 1292<if(dfa.specialStateSTs)> 1293 : base(specialStateTransition) 1294<endif> 1295 { 1296 this.recognizer = recognizer; 1297 this.decisionNumber = <dfa.decisionNumber>; 1298 this.eot = DFA<dfa.decisionNumber>_eot; 1299 this.eof = DFA<dfa.decisionNumber>_eof; 1300 this.min = DFA<dfa.decisionNumber>_min; 1301 this.max = DFA<dfa.decisionNumber>_max; 1302 this.accept = DFA<dfa.decisionNumber>_accept; 1303 this.special = DFA<dfa.decisionNumber>_special; 1304 this.transition = DFA<dfa.decisionNumber>_transition; 1305 } 1306 1307 public override string Description { get { return "<dfa.description>"; } } 1308 1309 public override void Error(NoViableAltException nvae) 1310 { 1311 DebugRecognitionException(nvae); 1312 } 1313}<\n> 1314<if(dfa.specialStateSTs)> 1315private int SpecialStateTransition<dfa.decisionNumber>(DFA dfa, int s, IIntStream _input)<! throws NoViableAltException!> 1316{ 1317 <if(LEXER)> 1318 IIntStream input = _input; 1319 <endif> 1320 <if(PARSER)> 1321 ITokenStream input = (ITokenStream)_input; 1322 <endif> 1323 <if(TREE_PARSER)> 1324 ITreeNodeStream input = (ITreeNodeStream)_input; 1325 <endif> 1326 int _s = s; 1327 switch (s) 1328 { 1329 <dfa.specialStateSTs:{state | 1330 case <i0>:<! compressed special state numbers 0..n-1 !> 1331 <state>}; separator="\n"> 1332 } 1333<if(backtracking)> 1334 if (state.backtracking > 0) {state.failed=true; return -1;} 1335<endif> 1336 NoViableAltException nvae = new NoViableAltException(dfa.Description, <dfa.decisionNumber>, _s, input); 1337 dfa.Error(nvae); 1338 throw nvae; 1339} 1340<endif> 1341>> 1342 1343/** A state in a cyclic DFA; it's a special state and part of a big switch on 1344 * state. 1345 */ 1346cyclicDFAState(decisionNumber,stateNumber,edges,needErrorClause,semPredState) ::= << 1347int LA<decisionNumber>_<stateNumber> = input.LA(1);<\n> 1348<if(semPredState)> 1349<! get next lookahead symbol to test edges, then rewind !> 1350<\n>int index<decisionNumber>_<stateNumber> = input.Index; 1351input.Rewind(); 1352<endif> 1353s = -1; 1354<edges; separator="\nelse "> 1355<if(semPredState)> 1356<! return input cursor to state before we rewound !> 1357<\n>input.Seek(index<decisionNumber>_<stateNumber>); 1358<endif> 1359if (s >= 0) return s; 1360break; 1361>> 1362 1363/** Just like a fixed DFA edge, test the lookahead and indicate what 1364 * state to jump to next if successful. 1365 */ 1366cyclicDFAEdge(labelExpr, targetStateNumber, edgeNumber, predicates) ::= << 1367if ((<labelExpr>)<if(predicates)> && (<predicates>)<endif>) {s = <targetStateNumber>;}<\n> 1368>> 1369 1370/** An edge pointing at end-of-token; essentially matches any char; 1371 * always jump to the target. 1372 */ 1373eotDFAEdge(targetStateNumber,edgeNumber, predicates) ::= << 1374s = <targetStateNumber>;<\n> 1375>> 1376 1377 1378// D F A E X P R E S S I O N S 1379 1380andPredicates(left,right) ::= "(<left>&&<right>)" 1381 1382orPredicates(operands) ::= "(<first(operands)><rest(operands):{o | ||<o>}>)" 1383 1384notPredicate(pred) ::= "!(<evalPredicate(...)>)" 1385 1386evalPredicate(pred,description) ::= "(<pred>)" 1387 1388evalSynPredicate(pred,description) ::= "EvaluatePredicate(<pred>_fragment)" 1389 1390lookaheadTest(atom,k,atomAsInt) ::= "LA<decisionNumber>_<stateNumber>==<atom>" 1391 1392/** Sometimes a lookahead test cannot assume that LA(k) is in a temp variable 1393 * somewhere. Must ask for the lookahead directly. 1394 */ 1395isolatedLookaheadTest(atom,k,atomAsInt) ::= "input.LA(<k>)==<atom>" 1396 1397lookaheadRangeTest(lower,upper,k,rangeNumber,lowerAsInt,upperAsInt) ::= <% 1398(LA<decisionNumber>_<stateNumber><ge()><lower> && LA<decisionNumber>_<stateNumber><le()><upper>) 1399%> 1400 1401isolatedLookaheadRangeTest(lower,upper,k,rangeNumber,lowerAsInt,upperAsInt) ::= "(input.LA(<k>)<ge()><lower> && input.LA(<k>)<le()><upper>)" 1402 1403le() ::= "\<=" 1404ge() ::= ">=" 1405 1406setTest(ranges) ::= << 1407<ranges; separator="||"> 1408>> 1409 1410// A T T R I B U T E S 1411 1412attributeScope(scope) ::= << 1413<if(scope.attributes)> 1414protected sealed partial class <scope.name>_scope 1415{ 1416 <scope.attributes:{it|public <it.decl>;}; separator="\n"> 1417 1418 public <scope.name>_scope(<grammar.recognizerName> grammar) { OnCreated(grammar); } 1419 partial void OnCreated(<grammar.recognizerName> grammar); 1420} 1421<if(scope.actions.scopeinit)> 1422protected void <scope.name>_scopeInit( <scope.name>_scope scope ) 1423{ 1424 <scope.actions.scopeinit> 1425} 1426<else> 1427partial void <scope.name>_scopeInit( <scope.name>_scope scope ); 1428<endif> 1429<if(scope.actions.scopeafter)> 1430protected void <scope.name>_scopeAfter( <scope.name>_scope scope ) 1431{ 1432 <scope.actions.scopeafter> 1433} 1434<else> 1435partial void <scope.name>_scopeAfter( <scope.name>_scope scope ); 1436<endif> 1437protected readonly ListStack\<<scope.name>_scope\> <scope.name>_stack = new ListStack\<<scope.name>_scope\>(); 1438<endif> 1439>> 1440 1441globalAttributeScope(scope) ::= << 1442<attributeScope(...)> 1443>> 1444 1445ruleAttributeScope(scope) ::= << 1446<attributeScope(...)> 1447>> 1448 1449returnStructName(it) ::= "<it.name>_return" 1450 1451returnType(ruleDescriptor) ::= <% 1452<if(ruleDescriptor.returnScope.attributes && ruleDescriptor.hasMultipleReturnValues)> 1453 <ruleDescriptor.grammar.recognizerName>.<ruleDescriptor:returnStructName()> 1454<elseif(ruleDescriptor.hasMultipleReturnValues)> 1455 <ruleReturnBaseType()> 1456<elseif(ruleDescriptor.hasSingleReturnValue)> 1457 <ruleDescriptor.singleValueReturnType> 1458<else> 1459 void 1460<endif> 1461%> 1462 1463/** Generate the C# type associated with a single or multiple return 1464 * values. 1465 */ 1466ruleLabelType(referencedRule) ::= <% 1467<if(referencedRule.returnScope.attributes&&referencedRule.hasMultipleReturnValues)> 1468 <referencedRule.grammar.recognizerName>.<referencedRule:returnStructName()> 1469<elseif(referencedRule.hasMultipleReturnValues)> 1470 <ruleReturnBaseType()> 1471<elseif(referencedRule.hasSingleReturnValue)> 1472 <referencedRule.singleValueReturnType> 1473<else> 1474 void 1475<endif> 1476%> 1477 1478delegateName(it) ::= << 1479<if(it.label)><it.label><else>g<it.name><endif> 1480>> 1481 1482/** Using a type to init value map, try to init a type; if not in table 1483 * must be an object, default value is "null". 1484 */ 1485initValue(typeName) ::= << 1486default(<typeName>) 1487>> 1488 1489/** Define a rule label including default value */ 1490ruleLabelDef(label) ::= <% 1491<ruleLabelType(label.referencedRule)> <label.label.text> = <initValue(ruleLabelType(label.referencedRule))>; 1492%> 1493 1494/** Define a return struct for a rule if the code needs to access its 1495 * start/stop tokens, tree stuff, attributes, ... Leave a hole for 1496 * subgroups to stick in members. 1497 */ 1498returnScope(scope) ::= << 1499<if(scope.attributes && ruleDescriptor.hasMultipleReturnValues)> 1500<returnScopeModifier(grammar=grammar,ruleDescriptor=ruleDescriptor)> sealed partial class <ruleDescriptor:returnStructName()> : <ruleReturnBaseType()><@ruleReturnInterfaces()> 1501{ 1502 <scope.attributes:{it|public <it.decl>;}; separator="\n"> 1503 <@ruleReturnMembers()> 1504} 1505<endif> 1506>> 1507 1508ruleReturnBaseType() ::= <% 1509<if(TREE_PARSER)>Tree<else>Parser<endif>RuleReturnScope\<<labelType>> 1510%> 1511 1512@returnScope.ruleReturnMembers() ::= << 1513public <ruleDescriptor:returnStructName()>(<grammar.recognizerName> grammar) {OnCreated(grammar);} 1514partial void OnCreated(<grammar.recognizerName> grammar); 1515>> 1516 1517parameterScope(scope) ::= << 1518<scope.attributes:{it|<it.decl>}; separator=", "> 1519>> 1520 1521parameterAttributeRef(attr) ::= << 1522<attr.name; format="id"> 1523>> 1524 1525parameterSetAttributeRef(attr,expr) ::= << 1526<attr.name; format="id"> =<expr>; 1527>> 1528 1529scopeAttributeRef(scope,attr,index,negIndex) ::= <% 1530<if(negIndex)> 1531<scope>_stack[<scope>_stack.Count - <negIndex> - 1].<attr.name; format="id"> 1532<else> 1533<if(index)> 1534<scope>_stack[<index>].<attr.name; format="id"> 1535<else> 1536<scope>_stack.Peek().<attr.name; format="id"> 1537<endif> 1538<endif> 1539%> 1540 1541scopeSetAttributeRef(scope,attr,expr,index,negIndex) ::= <% 1542<if(negIndex)> 1543<scope>_stack[<scope>_stack.Count - <negIndex> - 1].<attr.name; format="id"> = <expr>; 1544<else> 1545<if(index)> 1546<scope>_stack[<index>].<attr.name; format="id"> = <expr>; 1547<else> 1548<scope>_stack.Peek().<attr.name; format="id"> = <expr>; 1549<endif> 1550<endif> 1551%> 1552 1553/** $x is either global scope or x is rule with dynamic scope; refers 1554 * to stack itself not top of stack. This is useful for predicates 1555 * like {$function.Count>0 && $function::name.Equals("foo")}? 1556 */ 1557isolatedDynamicScopeRef(scope) ::= "<scope>_stack" 1558 1559/** reference an attribute of rule; might only have single return value */ 1560ruleLabelRef(referencedRule,scope,attr) ::= <% 1561<if(referencedRule.hasMultipleReturnValues)> 1562(<scope>!=null?<scope>.<attr.name; format="id">:<initValue(attr.type)>) 1563<else> 1564<scope> 1565<endif> 1566%> 1567 1568returnAttributeRef(ruleDescriptor,attr) ::= <% 1569<if(ruleDescriptor.hasMultipleReturnValues)> 1570retval.<attr.name; format="id"> 1571<else> 1572<attr.name; format="id"> 1573<endif> 1574%> 1575 1576returnSetAttributeRef(ruleDescriptor,attr,expr) ::= <% 1577<if(ruleDescriptor.hasMultipleReturnValues)> 1578retval.<attr.name; format="id"> =<expr>; 1579<else> 1580<attr.name; format="id"> =<expr>; 1581<endif> 1582%> 1583 1584/** How to translate $tokenLabel */ 1585tokenLabelRef(label) ::= "<label>" 1586 1587/** ids+=ID {$ids} or e+=expr {$e} */ 1588listLabelRef(label) ::= "list_<label>" 1589 1590 1591// not sure the next are the right approach 1592 1593tokenLabelPropertyRef_text(scope,attr) ::= "(<scope>!=null?<scope>.Text:null)" 1594tokenLabelPropertyRef_type(scope,attr) ::= "(<scope>!=null?<scope>.Type:0)" 1595tokenLabelPropertyRef_line(scope,attr) ::= "(<scope>!=null?<scope>.Line:0)" 1596tokenLabelPropertyRef_pos(scope,attr) ::= "(<scope>!=null?<scope>.CharPositionInLine:0)" 1597tokenLabelPropertyRef_channel(scope,attr) ::= "(<scope>!=null?<scope>.Channel:0)" 1598tokenLabelPropertyRef_index(scope,attr) ::= "(<scope>!=null?<scope>.TokenIndex:0)" 1599tokenLabelPropertyRef_tree(scope,attr) ::= "<scope>_tree" 1600tokenLabelPropertyRef_int(scope,attr) ::= "(<scope>!=null?int.Parse(<scope>.Text):0)" 1601 1602ruleLabelPropertyRef_start(scope,attr) ::= "(<scope>!=null?((<labelType>)<scope>.Start):default(<labelType>))" 1603ruleLabelPropertyRef_stop(scope,attr) ::= "(<scope>!=null?((<labelType>)<scope>.Stop):default(<labelType>))" 1604ruleLabelPropertyRef_tree(scope,attr) ::= "(<scope>!=null?((<ASTLabelType>)<scope>.Tree):default(<ASTLabelType>))" 1605ruleLabelPropertyRef_text(scope,attr) ::= <% 1606<if(TREE_PARSER)> 1607(<scope>!=null?(input.TokenStream.ToString( 1608 input.TreeAdaptor.GetTokenStartIndex(<scope>.Start), 1609 input.TreeAdaptor.GetTokenStopIndex(<scope>.Start))):null) 1610<else> 1611(<scope>!=null?input.ToString(<scope>.Start,<scope>.Stop):null) 1612<endif> 1613%> 1614 1615ruleLabelPropertyRef_st(scope,attr) ::= "(<scope>!=null?<scope>.Template:null)" 1616 1617/** Isolated $RULE ref ok in lexer as it's a Token */ 1618lexerRuleLabel(label) ::= "<label>" 1619 1620lexerRuleLabelPropertyRef_type(scope,attr) ::= 1621 "(<scope>!=null?<scope>.Type:0)" 1622 1623lexerRuleLabelPropertyRef_line(scope,attr) ::= 1624 "(<scope>!=null?<scope>.Line:0)" 1625 1626lexerRuleLabelPropertyRef_pos(scope,attr) ::= 1627 "(<scope>!=null?<scope>.CharPositionInLine:-1)" 1628 1629lexerRuleLabelPropertyRef_channel(scope,attr) ::= 1630 "(<scope>!=null?<scope>.Channel:0)" 1631 1632lexerRuleLabelPropertyRef_index(scope,attr) ::= 1633 "(<scope>!=null?<scope>.TokenIndex:0)" 1634 1635lexerRuleLabelPropertyRef_text(scope,attr) ::= 1636 "(<scope>!=null?<scope>.Text:null)" 1637 1638lexerRuleLabelPropertyRef_int(scope,attr) ::= 1639 "(<scope>!=null?int.Parse(<scope>.Text):0)" 1640 1641// Somebody may ref $template or $tree or $stop within a rule: 1642rulePropertyRef_start(scope,attr) ::= "retval.Start" 1643rulePropertyRef_stop(scope,attr) ::= "retval.Stop" 1644rulePropertyRef_tree(scope,attr) ::= "retval.Tree" 1645rulePropertyRef_text(scope,attr) ::= <% 1646<if(TREE_PARSER)> 1647input.TokenStream.ToString( 1648 input.TreeAdaptor.GetTokenStartIndex(retval.Start), 1649 input.TreeAdaptor.GetTokenStopIndex(retval.Start)) 1650<else> 1651input.ToString(retval.Start,input.LT(-1)) 1652<endif> 1653%> 1654rulePropertyRef_st(scope,attr) ::= "retval.Template" 1655 1656lexerRulePropertyRef_text(scope,attr) ::= "Text" 1657lexerRulePropertyRef_type(scope,attr) ::= "_type" 1658lexerRulePropertyRef_line(scope,attr) ::= "state.tokenStartLine" 1659lexerRulePropertyRef_pos(scope,attr) ::= "state.tokenStartCharPositionInLine" 1660lexerRulePropertyRef_index(scope,attr) ::= "-1" // undefined token index in lexer 1661lexerRulePropertyRef_channel(scope,attr) ::= "_channel" 1662lexerRulePropertyRef_start(scope,attr) ::= "state.tokenStartCharIndex" 1663lexerRulePropertyRef_stop(scope,attr) ::= "(CharIndex-1)" 1664lexerRulePropertyRef_int(scope,attr) ::= "int.Parse(<scope>.Text)" 1665 1666// setting $st and $tree is allowed in local rule. everything else 1667// is flagged as error 1668ruleSetPropertyRef_tree(scope,attr,expr) ::= "retval.Tree = <expr>;" 1669ruleSetPropertyRef_st(scope,attr,expr) ::= "retval.Template =<expr>;" 1670 1671/** How to execute an action (only when not backtracking) */ 1672execAction(action) ::= <% 1673<if(backtracking)> 1674if (<actions.(actionScope).synpredgate>)<\n> 1675{<\n> 1676<@indentedAction()><\n> 1677} 1678<else> 1679<action> 1680<endif> 1681%> 1682 1683@execAction.indentedAction() ::= << 1684 <action> 1685>> 1686 1687/** How to always execute an action even when backtracking */ 1688execForcedAction(action) ::= "<action>" 1689 1690// M I S C (properties, etc...) 1691 1692bitset(name, words64) ::= << 1693public static readonly BitSet <name> = new BitSet(new ulong[]{<words64:{it|<it>UL};separator=",">}); 1694>> 1695 1696codeFileExtension() ::= ".cs" 1697 1698true_value() ::= "true" 1699false_value() ::= "false" 1700