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 32 csharpVisibilityMap ::= [ 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 */ 43 outputFile( 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> 77 using System.Collections.Generic; 78 using Antlr.Runtime; 79 using Antlr.Runtime.Misc; 80 <if(TREE_PARSER)> 81 using Antlr.Runtime.Tree; 82 using RewriteRuleITokenStream = Antlr.Runtime.Tree.RewriteRuleTokenStream; 83 <endif> 84 using ConditionalAttribute = System.Diagnostics.ConditionalAttribute; 85 <@end> 86 <if(actions.(actionScope).namespace)> 87 namespace <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 98 lexerInputStreamType() ::= << 99 <actions.(actionScope).inputStreamType; null="ICharStream"> 100 >> 101 102 lexer(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 */ 205 filteringNextToken() ::= << 206 public 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 252 public override void Memoize(IIntStream input, int ruleIndex, int ruleStartIndex) 253 { 254 if (state.backtracking > 1) 255 base.Memoize(input, ruleIndex, ruleStartIndex); 256 } 257 258 public 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 267 actionGate() ::= "state.backtracking == 0" 268 269 filteringActionGate() ::= "state.backtracking == 1" 270 271 /** How to generate a parser */ 272 genericParser(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) 389 parserModifier(grammar, actions) ::= << 390 <if(grammar.grammarIsRoot)><actions.(actionScope).modifier; null="public"><else>public<endif> 391 >> 392 393 parserCtorBody() ::= << 394 <if(memoize)> 395 <if(grammar.grammarIsRoot)> 396 this.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 403 parser(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 */ 412 treeParser(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 */ 426 synpredRule(ruleName, ruleDescriptor, block, description, nakedBlock) ::= 427 << 428 [Conditional("ANTLR_TRACE")] 429 protected virtual void EnterRule_<ruleName>_fragment() {} 430 [Conditional("ANTLR_TRACE")] 431 protected virtual void LeaveRule_<ruleName>_fragment() {} 432 433 // $ANTLR start <ruleName> 434 public <!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 454 insertLexerSynpreds(synpreds) ::= << 455 <insertSynpreds(synpreds)> 456 >> 457 458 insertSynpreds(synpreds) ::= << 459 <if(synpreds)> 460 #region Synpreds 461 private 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 488 ruleMemoization(name) ::= << 489 <if(memoize)> 490 if (state.backtracking > 0 && AlreadyParsedRule(input, <ruleDescriptor.index>)) { <returnFromRule()> } 491 <endif> 492 >> 493 494 /** How to test for failure and return from rule */ 495 checkRuleBacktrackFailure() ::= << 496 <if(backtracking)>if (state.failed) <returnFromRule()><endif> 497 >> 498 499 /** This rule has failed, exit indicating failure during backtrack */ 500 ruleBacktrackFailure() ::= << 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 */ 507 rule(ruleName,ruleDescriptor,block,emptyRule,description,exceptions,finally,memoize) ::= << 508 <ruleAttributeScope(scope=ruleDescriptor.ruleScope)> 509 <returnScope(ruleDescriptor.returnScope)> 510 511 [Conditional("ANTLR_TRACE")] 512 protected virtual void EnterRule_<ruleName>() {} 513 [Conditional("ANTLR_TRACE")] 514 protected 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 572 ruleModifier(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 577 returnScopeModifier(grammar,ruleDescriptor) ::= << 578 <if(grammar.grammarIsRoot)><csharpVisibilityMap.(ruleDescriptor.modifier); null="private"><else>public<endif> 579 >> 580 581 catch(decl,action) ::= << 582 catch (<e.decl>) 583 { 584 <e.action> 585 } 586 >> 587 588 ruleDeclarations() ::= << 589 <if(ruleDescriptor.hasMultipleReturnValues)> 590 <returnType(ruleDescriptor)> retval = new <returnType(ruleDescriptor)>(); 591 retval.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)> 598 int <ruleDescriptor.name>_StartIndex = input.Index; 599 <endif> 600 >> 601 602 ruleScopeSetUp() ::= << 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 607 ruleScopeCleanUp() ::= << 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 612 ruleLabelDefs() ::= << 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 626 lexerRuleLabelDefs() ::= << 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 644 returnFromRule() ::= <% 645 return 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 659 ruleCleanUp() ::= << 660 <if(ruleDescriptor.hasMultipleReturnValues)> 661 <if(!TREE_PARSER)> 662 retval.Stop = (<labelType>)input.LT(-1); 663 <endif> 664 <endif> 665 >> 666 667 memoize() ::= << 668 <if(memoize)> 669 <if(backtracking)> 670 if (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 */ 678 lexerRule(ruleName,nakedBlock,ruleDescriptor,block,memoize) ::= << 679 680 [Conditional("ANTLR_TRACE")] 681 protected virtual void EnterRule_<ruleName>() {} 682 [Conditional("ANTLR_TRACE")] 683 protected 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 */ 729 tokensRule(ruleName,nakedBlock,args,block,ruleDescriptor) ::= << 730 731 public 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 */ 740 block(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= << 741 // <fileName>:<description> 742 int alt<decisionNumber>=<maxAlt>; 743 <decls> 744 <@predecision()> 745 try { DebugEnterSubRule(<decisionNumber>); 746 try { DebugEnterDecision(<decisionNumber>, decisionCanBacktrack[<decisionNumber>]); 747 <decision> 748 } finally { DebugExitDecision(<decisionNumber>); } 749 <@postdecision()> 750 <@prebranch()> 751 switch (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 */ 760 ruleBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= << 761 // <fileName>:<description> 762 int alt<decisionNumber>=<maxAlt>; 763 <decls> 764 <@predecision()> 765 try { DebugEnterDecision(<decisionNumber>, decisionCanBacktrack[<decisionNumber>]); 766 <decision> 767 } finally { DebugExitDecision(<decisionNumber>); } 768 <@postdecision()> 769 switch (alt<decisionNumber>) 770 { 771 <alts:{a|<altSwitchCase(i,a)>}> 772 } 773 >> 774 775 ruleBlockSingleAlt(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,description) ::= << 776 // <fileName>:<description> 777 <decls> 778 <@prealt()> 779 DebugEnterAlt(1); 780 <alts> 781 <@postalt()> 782 >> 783 784 /** A special case of a (...) subrule with a single alternative */ 785 blockSingleAlt(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,description) ::= << 786 // <fileName>:<description> 787 <decls> 788 <@prealt()> 789 DebugEnterAlt(1); 790 <alts> 791 <@postalt()> 792 >> 793 794 /** A (..)+ block with 1 or more alternatives */ 795 positiveClosureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= << 796 // <fileName>:<description> 797 int cnt<decisionNumber>=0; 798 <decls> 799 <@preloop()> 800 try { DebugEnterSubRule(<decisionNumber>); 801 while (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 } 824 loop<decisionNumber>: 825 ; 826 827 } finally { DebugExitSubRule(<decisionNumber>); } 828 <@postloop()> 829 >> 830 831 positiveClosureBlockSingleAlt ::= positiveClosureBlock 832 833 /** A (..)* block with 1 or more alternatives */ 834 closureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= << 835 // <fileName>:<description> 836 <decls> 837 <@preloop()> 838 try { DebugEnterSubRule(<decisionNumber>); 839 while (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 855 loop<decisionNumber>: 856 ; 857 858 } finally { DebugExitSubRule(<decisionNumber>); } 859 <@postloop()> 860 >> 861 862 closureBlockSingleAlt ::= 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 */ 867 optionalBlock ::= block 868 869 optionalBlockSingleAlt ::= 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 */ 875 altSwitchCase(altNum,alt) ::= << 876 case <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 */ 884 alt(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 */ 897 noRewrite(rewriteBlockLevel, treeLevel) ::= "" 898 899 // E L E M E N T S 900 901 /** Dump the elements one per line */ 902 element(it) ::= <% 903 <@prematch()> 904 DebugLocation(<it.line>, <it.pos>);<\n> 905 <it.el><\n> 906 %> 907 908 /** match a token optionally with a label in front */ 909 tokenRef(token,label,elementIndex,terminalOptions) ::= << 910 <if(label)><label>=(<labelType>)<endif>Match(input,<token>,Follow._<token>_in_<ruleName><elementIndex>); <checkRuleBacktrackFailure()> 911 >> 912 913 /** ids+=ID */ 914 tokenRefAndListLabel(token,label,elementIndex,terminalOptions) ::= << 915 <tokenRef(...)> 916 <listLabelElem(elem=label,elemType=labelType,...)> 917 >> 918 919 listLabelElem(label,elem,elemType) ::= << 920 if (list_<label>==null) list_<label>=new List\<<elemType; null={<labelType>}>\>(); 921 list_<label>.Add(<elem>);<\n> 922 >> 923 924 /** match a character */ 925 charRef(char,label) ::= << 926 <if(label)> 927 <label> = input.LA(1);<\n> 928 <endif> 929 Match(<char>); <checkRuleBacktrackFailure()> 930 >> 931 932 /** match a character range */ 933 charRangeRef(a,b,label) ::= << 934 <if(label)> 935 <label> = input.LA(1);<\n> 936 <endif> 937 MatchRange(<a>,<b>); <checkRuleBacktrackFailure()> 938 >> 939 940 /** For now, sets are interval tests and must be tested inline */ 941 matchSet(s,label,terminalOptions,elementIndex,postmatchCode="") ::= << 942 <if(label)> 943 <matchSetLabel()> 944 <endif> 945 if (<s>) 946 { 947 input.Consume(); 948 <postmatchCode> 949 <if(!LEXER)>state.errorRecovery=false;<endif><if(backtracking)>state.failed=false;<endif> 950 } 951 else 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 969 matchSetUnchecked(s,label,elementIndex,postmatchCode=false) ::= <% 970 <if(label)> 971 <matchSetLabel()><\n> 972 <endif> 973 input.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 980 matchSetLabel() ::= <% 981 <if(LEXER)> 982 <label>= input.LA(1); 983 <else> 984 <label>=(<labelType>)input.LT(1); 985 <endif> 986 %> 987 988 matchRuleBlockSet ::= matchSet 989 990 matchSetAndListLabel(s,label,elementIndex,postmatchCode) ::= << 991 <matchSet(...)> 992 <listLabelElem(elem=label,elemType=labelType,...)> 993 >> 994 995 /** Match a string literal */ 996 lexerStringRef(string,label,elementIndex) ::= <% 997 <if(label)> 998 int <label>Start = CharIndex;<\n> 999 Match(<string>); <checkRuleBacktrackFailure()><\n> 1000 int <label>StartLine<elementIndex> = Line;<\n> 1001 int <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> 1006 Match(<string>); <checkRuleBacktrackFailure()><\n> 1007 <endif> 1008 %> 1009 1010 wildcard(token,label,elementIndex,terminalOptions) ::= << 1011 <if(label)> 1012 <label>=(<labelType>)input.LT(1);<\n> 1013 <endif> 1014 MatchAny(input); <checkRuleBacktrackFailure()> 1015 >> 1016 1017 wildcardAndListLabel(token,label,elementIndex,terminalOptions) ::= << 1018 <wildcard(...)> 1019 <listLabelElem(elem=label,elemType=labelType,...)> 1020 >> 1021 1022 /** Match . wildcard in lexer */ 1023 wildcardChar(label, elementIndex) ::= << 1024 <if(label)> 1025 <label> = input.LA(1);<\n> 1026 <endif> 1027 MatchAny(); <checkRuleBacktrackFailure()> 1028 >> 1029 1030 wildcardCharListLabel(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 */ 1041 ruleRef(rule,label,elementIndex,args,scope) ::= << 1042 PushFollow(Follow._<rule.name>_in_<ruleName><elementIndex>); 1043 <if(label)><label>=<endif><if(scope)><scope:delegateName()>.<endif><rule.name; format="id">(<args; separator=", ">); 1044 PopFollow(); 1045 <checkRuleBacktrackFailure()> 1046 >> 1047 1048 /** ids+=r */ 1049 ruleRefAndListLabel(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 */ 1060 lexerRuleRef(rule,label,args,elementIndex,scope) ::= <% 1061 <if(label)> 1062 int <label>Start<elementIndex> = CharIndex;<\n> 1063 int <label>StartLine<elementIndex> = Line;<\n> 1064 int <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 */ 1075 lexerRuleRefAndListLabel(rule,label,args,elementIndex,scope) ::= << 1076 <lexerRuleRef(...)> 1077 <listLabelElem(elem=label,elemType=labelType,...)> 1078 >> 1079 1080 /** EOF in the lexer */ 1081 lexerMatchEOF(label,elementIndex) ::= <% 1082 <if(label)> 1083 int <label>Start<elementIndex> = CharIndex;<\n> 1084 int <label>StartLine<elementIndex> = Line;<\n> 1085 int <label>StartCharPos<elementIndex> = CharPositionInLine;<\n> 1086 Match(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> 1091 Match(EOF); <checkRuleBacktrackFailure()> 1092 <endif> 1093 %> 1094 1095 // used for left-recursive rules 1096 recRuleDefArg() ::= "int <recRuleArg()>" 1097 recRuleArg() ::= "_p" 1098 recRuleAltPredicate(ruleName,opPrec) ::= "<recRuleArg()> \<= <opPrec>" 1099 recRuleSetResultAction() ::= "root_0=$<ruleName>_primary.tree;" 1100 recRuleSetReturnAction(src,name) ::= "$<name>=$<src>.<name>;" 1101 1102 /** match ^(root children) in tree parser */ 1103 tree(root, actionsAfterRoot, children, nullableChildList, 1104 enclosingTreeLevel, treeLevel) ::= << 1105 <root:element()> 1106 <actionsAfterRoot:element()> 1107 <if(nullableChildList)> 1108 if (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> 1115 Match(input, TokenTypes.Down, null); <checkRuleBacktrackFailure()> 1116 <children:element()> 1117 Match(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 */ 1124 validateSemanticPredicate(pred,description) ::= << 1125 if (!(<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 1134 dfaState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= << 1135 int LA<decisionNumber>_<stateNumber> = input.LA(<k>);<\n> 1136 <edges; separator="\nelse "> 1137 else 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 */ 1156 dfaOptionalBlockState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= << 1157 int 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 */ 1167 dfaLoopbackState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= << 1168 int LA<decisionNumber>_<stateNumber> = input.LA(<k>);<\n> 1169 <edges; separator="\nelse "><\n> 1170 <if(eotPredictsAlt)> 1171 <if(!edges)> 1172 alt<decisionNumber> = <eotPredictsAlt>;<! if no edges, don't gen ELSE !> 1173 <else> 1174 else 1175 { 1176 alt<decisionNumber> = <eotPredictsAlt>; 1177 }<\n> 1178 <endif> 1179 <endif> 1180 >> 1181 1182 /** An accept state indicates a unique alternative has been predicted */ 1183 dfaAcceptState(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 */ 1189 dfaEdge(labelExpr, targetState, predicates) ::= << 1190 if ((<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 */ 1201 dfaStateSwitch(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= << 1202 switch (input.LA(<k>)) 1203 { 1204 <edges; separator="\n"> 1205 default: 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 1221 dfaOptionalBlockStateSwitch(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= << 1222 switch (input.LA(<k>)) 1223 { 1224 <edges; separator="\n"> 1225 }<\n> 1226 >> 1227 1228 dfaLoopbackStateSwitch(k, edges,eotPredictsAlt,description,stateNumber,semPredState) ::= << 1229 switch (input.LA(<k>)) 1230 { 1231 <edges; separator="\n"> 1232 <if(eotPredictsAlt)> 1233 default: 1234 alt<decisionNumber>=<eotPredictsAlt>; 1235 break;<\n> 1236 <endif> 1237 }<\n> 1238 >> 1239 1240 dfaEdgeSwitch(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 */ 1254 dfaDecision(decisionNumber,description) ::= << 1255 try 1256 { 1257 alt<decisionNumber> = dfa<decisionNumber>.Predict(input); 1258 } 1259 catch (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 */ 1274 cyclicDFA(dfa) ::= << 1275 private 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)> 1336 private 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 */ 1367 cyclicDFAState(decisionNumber,stateNumber,edges,needErrorClause,semPredState) ::= << 1368 int 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; 1372 input.Rewind(); 1373 <endif> 1374 s = -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> 1380 if (s >= 0) return s; 1381 break; 1382 >> 1383 1384 /** Just like a fixed DFA edge, test the lookahead and indicate what 1385 * state to jump to next if successful. 1386 */ 1387 cyclicDFAEdge(labelExpr, targetStateNumber, edgeNumber, predicates) ::= << 1388 if ((<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 */ 1394 eotDFAEdge(targetStateNumber,edgeNumber, predicates) ::= << 1395 s = <targetStateNumber>;<\n> 1396 >> 1397 1398 1399 // D F A E X P R E S S I O N S 1400 1401 andPredicates(left,right) ::= "(<left>&&<right>)" 1402 1403 orPredicates(operands) ::= "(<first(operands)><rest(operands):{o | ||<o>}>)" 1404 1405 notPredicate(pred) ::= "!(<evalPredicate(...)>)" 1406 1407 evalPredicate(pred,description) ::= "(<pred>)" 1408 1409 evalSynPredicate(pred,description) ::= "EvaluatePredicate(<pred>_fragment)" 1410 1411 lookaheadTest(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 */ 1416 isolatedLookaheadTest(atom,k,atomAsInt) ::= "input.LA(<k>)==<atom>" 1417 1418 lookaheadRangeTest(lower,upper,k,rangeNumber,lowerAsInt,upperAsInt) ::= <% 1419 (LA<decisionNumber>_<stateNumber><ge()><lower> && LA<decisionNumber>_<stateNumber><le()><upper>) 1420 %> 1421 1422 isolatedLookaheadRangeTest(lower,upper,k,rangeNumber,lowerAsInt,upperAsInt) ::= "(input.LA(<k>)<ge()><lower> && input.LA(<k>)<le()><upper>)" 1423 1424 le() ::= "\<=" 1425 ge() ::= ">=" 1426 1427 setTest(ranges) ::= << 1428 <ranges; separator="||"> 1429 >> 1430 1431 // A T T R I B U T E S 1432 1433 attributeScope(scope) ::= << 1434 <if(scope.attributes)> 1435 protected sealed partial class <scope.name>_scope 1436 { 1437 <scope.attributes:{it|public <it.decl>;}; separator="\n"> 1438 } 1439 <if(scope.actions.scopeinit)> 1440 protected void <scope.name>_scopeInit( <scope.name>_scope scope ) 1441 { 1442 <scope.actions.scopeinit> 1443 } 1444 <else> 1445 protected virtual void <scope.name>_scopeInit( <scope.name>_scope scope ) {} 1446 <endif> 1447 <if(scope.actions.scopeafter)> 1448 protected void <scope.name>_scopeAfter( <scope.name>_scope scope ) 1449 { 1450 <scope.actions.scopeafter> 1451 } 1452 <else> 1453 protected virtual void <scope.name>_scopeAfter( <scope.name>_scope scope ) {} 1454 <endif> 1455 protected readonly ListStack\<<scope.name>_scope\> <scope.name>_stack = new ListStack\<<scope.name>_scope\>(); 1456 <endif> 1457 >> 1458 1459 globalAttributeScope(scope) ::= << 1460 <attributeScope(...)> 1461 >> 1462 1463 ruleAttributeScope(scope) ::= << 1464 <attributeScope(...)> 1465 >> 1466 1467 returnStructName(it) ::= "<it.name>_return" 1468 1469 returnType(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 */ 1484 ruleLabelType(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 1496 delegateName(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 */ 1503 initValue(typeName) ::= << 1504 default(<typeName>) 1505 >> 1506 1507 /** Define a rule label including default value */ 1508 ruleLabelDef(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 */ 1516 returnScope(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 1526 ruleReturnBaseType() ::= <% 1527 <if(TREE_PARSER)>Tree<else>Parser<endif>RuleReturnScope\<<labelType>> 1528 %> 1529 1530 @returnScope.ruleReturnMembers() ::= << 1531 >> 1532 1533 parameterScope(scope) ::= << 1534 <scope.attributes:{it|<it.decl>}; separator=", "> 1535 >> 1536 1537 parameterAttributeRef(attr) ::= << 1538 <attr.name; format="id"> 1539 >> 1540 1541 parameterSetAttributeRef(attr,expr) ::= << 1542 <attr.name; format="id"> =<expr>; 1543 >> 1544 1545 scopeAttributeRef(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 1557 scopeSetAttributeRef(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 */ 1573 isolatedDynamicScopeRef(scope) ::= "<scope>_stack" 1574 1575 /** reference an attribute of rule; might only have single return value */ 1576 ruleLabelRef(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 1584 returnAttributeRef(ruleDescriptor,attr) ::= <% 1585 <if(ruleDescriptor.hasMultipleReturnValues)> 1586 retval.<attr.name; format="id"> 1587 <else> 1588 <attr.name; format="id"> 1589 <endif> 1590 %> 1591 1592 returnSetAttributeRef(ruleDescriptor,attr,expr) ::= <% 1593 <if(ruleDescriptor.hasMultipleReturnValues)> 1594 retval.<attr.name; format="id"> =<expr>; 1595 <else> 1596 <attr.name; format="id"> =<expr>; 1597 <endif> 1598 %> 1599 1600 /** How to translate $tokenLabel */ 1601 tokenLabelRef(label) ::= "<label>" 1602 1603 /** ids+=ID {$ids} or e+=expr {$e} */ 1604 listLabelRef(label) ::= "list_<label>" 1605 1606 1607 // not sure the next are the right approach 1608 1609 tokenLabelPropertyRef_text(scope,attr) ::= "(<scope>!=null?<scope>.Text:null)" 1610 tokenLabelPropertyRef_type(scope,attr) ::= "(<scope>!=null?<scope>.Type:0)" 1611 tokenLabelPropertyRef_line(scope,attr) ::= "(<scope>!=null?<scope>.Line:0)" 1612 tokenLabelPropertyRef_pos(scope,attr) ::= "(<scope>!=null?<scope>.CharPositionInLine:0)" 1613 tokenLabelPropertyRef_channel(scope,attr) ::= "(<scope>!=null?<scope>.Channel:0)" 1614 tokenLabelPropertyRef_index(scope,attr) ::= "(<scope>!=null?<scope>.TokenIndex:0)" 1615 tokenLabelPropertyRef_tree(scope,attr) ::= "<scope>_tree" 1616 tokenLabelPropertyRef_int(scope,attr) ::= "(<scope>!=null?int.Parse(<scope>.Text):0)" 1617 1618 ruleLabelPropertyRef_start(scope,attr) ::= "(<scope>!=null?((<labelType>)<scope>.Start):default(<labelType>))" 1619 ruleLabelPropertyRef_stop(scope,attr) ::= "(<scope>!=null?((<labelType>)<scope>.Stop):default(<labelType>))" 1620 ruleLabelPropertyRef_tree(scope,attr) ::= "(<scope>!=null?((<ASTLabelType>)<scope>.Tree):default(<ASTLabelType>))" 1621 ruleLabelPropertyRef_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 1631 ruleLabelPropertyRef_st(scope,attr) ::= "(<scope>!=null?<scope>.Template:null)" 1632 1633 /** Isolated $RULE ref ok in lexer as it's a Token */ 1634 lexerRuleLabel(label) ::= "<label>" 1635 1636 lexerRuleLabelPropertyRef_type(scope,attr) ::= 1637 "(<scope>!=null?<scope>.Type:0)" 1638 1639 lexerRuleLabelPropertyRef_line(scope,attr) ::= 1640 "(<scope>!=null?<scope>.Line:0)" 1641 1642 lexerRuleLabelPropertyRef_pos(scope,attr) ::= 1643 "(<scope>!=null?<scope>.CharPositionInLine:-1)" 1644 1645 lexerRuleLabelPropertyRef_channel(scope,attr) ::= 1646 "(<scope>!=null?<scope>.Channel:0)" 1647 1648 lexerRuleLabelPropertyRef_index(scope,attr) ::= 1649 "(<scope>!=null?<scope>.TokenIndex:0)" 1650 1651 lexerRuleLabelPropertyRef_text(scope,attr) ::= 1652 "(<scope>!=null?<scope>.Text:null)" 1653 1654 lexerRuleLabelPropertyRef_int(scope,attr) ::= 1655 "(<scope>!=null?int.Parse(<scope>.Text):0)" 1656 1657 // Somebody may ref $template or $tree or $stop within a rule: 1658 rulePropertyRef_start(scope,attr) ::= "retval.Start" 1659 rulePropertyRef_stop(scope,attr) ::= "retval.Stop" 1660 rulePropertyRef_tree(scope,attr) ::= "retval.Tree" 1661 rulePropertyRef_text(scope,attr) ::= <% 1662 <if(TREE_PARSER)> 1663 input.TokenStream.ToString( 1664 input.TreeAdaptor.GetTokenStartIndex(retval.Start), 1665 input.TreeAdaptor.GetTokenStopIndex(retval.Start)) 1666 <else> 1667 input.ToString(retval.Start,input.LT(-1)) 1668 <endif> 1669 %> 1670 rulePropertyRef_st(scope,attr) ::= "retval.Template" 1671 1672 lexerRulePropertyRef_text(scope,attr) ::= "Text" 1673 lexerRulePropertyRef_type(scope,attr) ::= "_type" 1674 lexerRulePropertyRef_line(scope,attr) ::= "state.tokenStartLine" 1675 lexerRulePropertyRef_pos(scope,attr) ::= "state.tokenStartCharPositionInLine" 1676 lexerRulePropertyRef_index(scope,attr) ::= "-1" // undefined token index in lexer 1677 lexerRulePropertyRef_channel(scope,attr) ::= "_channel" 1678 lexerRulePropertyRef_start(scope,attr) ::= "state.tokenStartCharIndex" 1679 lexerRulePropertyRef_stop(scope,attr) ::= "(CharIndex-1)" 1680 lexerRulePropertyRef_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 1684 ruleSetPropertyRef_tree(scope,attr,expr) ::= "retval.Tree = <expr>;" 1685 ruleSetPropertyRef_st(scope,attr,expr) ::= "retval.Template =<expr>;" 1686 1687 /** How to execute an action (only when not backtracking) */ 1688 execAction(action) ::= <% 1689 <if(backtracking)> 1690 if (<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 */ 1704 execForcedAction(action) ::= "<action>" 1705 1706 // M I S C (properties, etc...) 1707 1708 bitset(name, words64) ::= << 1709 public static readonly BitSet <name> = new BitSet(new ulong[]{<words64:{it|<it>UL};separator=",">}); 1710 >> 1711 1712 codeFileExtension() ::= ".cs" 1713 1714 true_value() ::= "true" 1715 false_value() ::= "false" 1716