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