JavaScript.stg revision 324c4644fee44b9898524c09511bd33c3f12e2df
1group JavaScript; 2 3/** The overall file structure of a recognizer; stores methods for rules 4 * and cyclic DFAs plus support code. 5 */ 6outputFile(LEXER,PARSER,TREE_PARSER, actionScope, actions, 7 docComment, recognizer, 8 name, tokens, tokenNames, rules, cyclicDFAs, 9 bitsets, buildTemplate, buildAST, rewriteMode, profile, 10 backtracking, synpreds, memoize, numRules, 11 fileName, ANTLRVersion, generatedTimestamp, trace, 12 scopes, superClass, literals) ::= 13<< 14// $ANTLR <ANTLRVersion> <fileName> <generatedTimestamp> 15<actions.(actionScope).header> 16 17<@imports> 18<if(TREE_PARSER)> 19<endif> 20<@end> 21 22<docComment> 23<recognizer> 24>> 25 26lexer(grammar, name, tokens, scopes, rules, numRules, labelType="Token", 27 filterMode, superClass="org.antlr.runtime.Lexer") ::= << 28var <grammar.recognizerName> = function(input, state<grammar.delegators:{g|, <g:delegateName()>}>) { 29// alternate constructor @todo 30// public <grammar.recognizerName>(CharStream input<grammar.delegators:{g|, <g.recognizerName> <g:delegateName()>}>) 31// public <grammar.recognizerName>(CharStream input, RecognizerSharedState state<grammar.delegators:{g|, <g.recognizerName> <g:delegateName()>}>) { 32 if (!state) { 33 state = new org.antlr.runtime.RecognizerSharedState(); 34 } 35 36 (function(){ 37 <actions.lexer.members> 38 }).call(this); 39 40 <cyclicDFAs:{dfa | this.dfa<dfa.decisionNumber> = new <grammar.recognizerName>.DFA<dfa.decisionNumber>(this);}; separator="\n"> 41 <grammar.recognizerName>.superclass.constructor.call(this, input, state); 42 <if(memoize)> 43 <if(grammar.grammarIsRoot)> 44 this.state.ruleMemo = {}; 45 <endif> 46 <endif> 47 48 <grammar.directDelegates: 49 {g|this.<g:delegateName()> = new <g.recognizerName>(input, state<trunc(g.delegators):{p|, <p:delegateName()>}>, this);}; separator="\n"> 50 <grammar.delegators: 51 {g|this.<g:delegateName()> = <g:delegateName()>;}; separator="\n"> 52 <last(grammar.delegators):{g|this.gParent = this.<g:delegateName()>;}> 53 54 <actions.lexer.init> 55}; 56 57org.antlr.lang.augmentObject(<grammar.recognizerName>, { 58 <tokens:{<it.name>: <it.type>}; separator=",\n"> 59}); 60 61(function(){ 62var HIDDEN = org.antlr.runtime.Token.HIDDEN_CHANNEL, 63 EOF = org.antlr.runtime.Token.EOF; 64org.antlr.lang.extend(<grammar.recognizerName>, <@superClassName><superClass><@end>, { 65 <tokens:{<it.name> : <it.type>,}; separator="\n"> 66 <scopes:{<if(it.isDynamicGlobalScope)><globalAttributeScope(scope=it)><endif>}> 67 getGrammarFileName: function() { return "<fileName>"; } 68}); 69org.antlr.lang.augmentObject(<grammar.recognizerName>.prototype, { 70<if(filterMode)> 71 <filteringNextToken()> 72<endif> 73 <rules; separator=",\n\n"> 74 75 <synpreds:{p | <lexerSynpred(p)>}; separator=",\n"> 76}, true); // important to pass true to overwrite default implementations 77 78<cyclicDFAs:cyclicDFA()> <! dump tables for all DFA !> 79})(); 80>> 81 82/** A override of Lexer.nextToken() that backtracks over mTokens() looking 83 * for matches. No error can be generated upon error; just rewind, consume 84 * a token and then try again. backtracking needs to be set as well. 85 * Make rule memoization happen only at levels above 1 as we start mTokens 86 * at backtracking==1. 87 */ 88filteringNextToken() ::= << 89nextToken: function() { 90 while (true) { 91 if ( this.input.LA(1)==org.antlr.runtime.CharStream.EOF ) { 92 return org.antlr.runtime.Token.EOF_TOKEN; 93 } 94 this.state.token = null; 95 this.state.channel = org.antlr.runtime.Token.DEFAULT_CHANNEL; 96 this.state.tokenStartCharIndex = this.input.index(); 97 this.state.tokenStartCharPositionInLine = this.input.getCharPositionInLine(); 98 this.state.tokenStartLine = this.input.getLine(); 99 this.state.text = null; 100 try { 101 var m = this.input.mark(); 102 this.state.backtracking=1; <! means we won't throw slow exception !> 103 this.state.failed=false; 104 this.mTokens(); 105 this.state.backtracking=0; 106 <! mTokens backtracks with synpred at backtracking==2 107 and we set the synpredgate to allow actions at level 1. !> 108 if ( this.state.failed ) { 109 this.input.rewind(m); 110 this.input.consume(); <! advance one char and try again !> 111 } 112 else { 113 this.emit(); 114 return this.state.token; 115 } 116 } 117 catch (re) { 118 // shouldn't happen in backtracking mode, but... 119 if (re instanceof org.antlr.runtime.RecognitionException) { 120 this.reportError(re); 121 this.recover(re); 122 } else { 123 throw re; 124 } 125 } 126 } 127}, 128 129memoize: function(input, ruleIndex, ruleStartIndex) { 130 if (this.state.backtracking>1) { 131 <grammar.recognizerName>.superclass.prototype.memoize.call(this, input, ruleIndex, ruleStartIndex); 132 } 133}, 134 135alreadyParsedRule: function(input, ruleIndex) { 136 if (this.state.backtracking>1) { 137 return <grammar.recognizerName>.superclass.prototype.alreadyParsedRule.call(this, input, ruleIndex); 138 } 139 return false; 140}, 141 142 143>> 144 145actionGate() ::= "this.state.backtracking===0" 146 147filteringActionGate() ::= "this.state.backtracking===1" 148 149/** How to generate a parser */ 150genericParser(grammar, name, scopes, tokens, tokenNames, rules, numRules, 151 bitsets, inputStreamType, superClass, 152 ASTLabelType="Object", labelType, members, rewriteElementType) ::= << 153<! WARNING. bug in ST: this is cut-n-paste into Dbg.stg !> 154var <grammar.recognizerName> = function(input, state<grammar.delegators:{g|, <g:delegateName()>}>) { 155 if (!state) { 156 state = new org.antlr.runtime.RecognizerSharedState(); 157 } 158 159 (function(){ 160 <members> 161 }).call(this); 162 163 <grammar.recognizerName>.superclass.constructor.call(this, input, state); 164 165 <cyclicDFAs:{dfa | this.dfa<dfa.decisionNumber> = new <grammar.recognizerName>.DFA<dfa.decisionNumber>(this);}; separator="\n"> 166 167 <parserCtorBody()> 168 <grammar.directDelegates: 169 {g|this.<g:delegateName()> = new <g.recognizerName>(input, state<trunc(g.delegators):{p|, <p:delegateName()>}>, this);}; separator="\n"> 170 <grammar.indirectDelegates:{g | this.<g:delegateName()> = <g.delegator:delegateName()>.<g:delegateName()>;}; separator="\n"> 171 <last(grammar.delegators):{g|this.gParent = this.<g:delegateName()>;}> 172 173 /* @todo only create adaptor if output=AST */ 174 this.adaptor = new org.antlr.runtime.tree.CommonTreeAdaptor();<\n> 175}; 176 177org.antlr.lang.augmentObject(<grammar.recognizerName>, { 178 <tokens:{<it.name>: <it.type>}; separator=",\n"> 179}); 180 181(function(){ 182// public class variables 183var <tokens:{<it.name>= <it.type>}; separator=",\n ">; 184<if(TREE_PARSER)> 185var UP = org.antlr.runtime.Token.UP, 186 DOWN = org.antlr.runtime.Token.DOWN; 187<endif> 188 189 190// public instance methods/vars 191org.antlr.lang.extend(<grammar.recognizerName>, org.antlr.runtime.<@superClassName><superClass><@end>, { 192 <@members> 193 <@end> 194 <scopes:{<if(it.isDynamicGlobalScope)><globalAttributeScope(scope=it)><endif>}> 195 196 getTokenNames: function() { return <grammar.composite.rootGrammar.recognizerName>.tokenNames; }, 197 getGrammarFileName: function() { return "<fileName>"; } 198}); 199org.antlr.lang.augmentObject(<grammar.recognizerName>.prototype, { 200 201 <rules; separator=",\n\n"> 202 203<! generate rule/method definitions for imported rules so they 204 appear to be defined in this recognizer. !> 205 // Delegated rules 206<grammar.delegatedRules:{ruleDescriptor| 207 , <ruleDescriptor.name>: function(<ruleDescriptor.parameterScope:parameterScope(scope=it)>) \{ <if(ruleDescriptor.hasReturnValue)>return <endif>this.<ruleDescriptor.grammar:delegateName()>.<ruleDescriptor.name>(<ruleDescriptor.parameterScope.attributes:{a|<a.name>}; separator=", ">); \}}> 208 209 210 211 <synpreds:{p | <synpred(p)>}; separator=",\n"> 212 213}, true); // important to pass true to overwrite default implementations 214 215<cyclicDFAs:cyclicDFA()> <! dump tables for all DFA !> 216 217// public class variables 218org.antlr.lang.augmentObject(<grammar.recognizerName>, { 219<if(grammar.grammarIsRoot)> 220 tokenNames: ["\<invalid>", "\<EOR>", "\<DOWN>", "\<UP>", <tokenNames; separator=", ">],<\n> 221<endif> 222 <bitsets:bitset(name={FOLLOW_<it.name>_in_<it.inName><it.tokenIndex>}, 223 words64=it.bits); separator=",\n"> 224}); 225 226})(); 227>> 228 229parserCtorBody() ::= << 230<if(memoize)> 231<if(grammar.grammarIsRoot)> 232this.state.ruleMemo = {};<\n> <! index from 1..n !> 233<endif> 234<endif> 235<grammar.delegators: 236 {g|this.<g:delegateName()> = <g:delegateName()>;}; separator="\n"> 237>> 238 239parser(grammar, name, scopes, tokens, tokenNames, rules, numRules, bitsets, ASTLabelType="Object", superClass="Parser", labelType="Token", members={<actions.parser.members>}) ::= << 240<genericParser(inputStreamType="TokenStream", rewriteElementType="Token", ...)> 241>> 242 243/** How to generate a tree parser; same as parser except the input 244 * stream is a different type. 245 */ 246treeParser(grammar, name, scopes, tokens, tokenNames, globalAction, rules, numRules, bitsets, labelType={<ASTLabelType>}, ASTLabelType="var", superClass="tree.TreeParser", members={<actions.treeparser.members>}, filterMode) ::= << 247<genericParser(inputStreamType="TreeNodeStream", rewriteElementType="Node", ...)> 248>> 249 250/** A simpler version of a rule template that is specific to the imaginary 251 * rules created for syntactic predicates. As they never have return values 252 * nor parameters etc..., just give simplest possible method. Don't do 253 * any of the normal memoization stuff in here either; it's a waste. 254 * As predicates cannot be inlined into the invoking rule, they need to 255 * be in a rule by themselves. 256 */ 257synpredRule(ruleName, ruleDescriptor, block, description, nakedBlock) ::= 258<< 259// $ANTLR start "<ruleName>" 260<ruleName>_fragment: function(<ruleDescriptor.parameterScope:parameterScope(scope=it)>) { 261<if(trace)> 262 this.traceIn("<ruleName>_fragment", <ruleDescriptor.index>); 263 try { 264 <block> 265 } 266 finally { 267 this.traceOut("<ruleName>_fragment", <ruleDescriptor.index>); 268 } 269<else> 270 <block> 271<endif> 272}, 273// $ANTLR end "<ruleName>" 274>> 275 276synpred(name) ::= << 277<name>: function() { 278 this.state.backtracking++; 279 <@start()> 280 var start = this.input.mark(); 281 try { 282 this.<name>_fragment(); // can never throw exception 283 } catch (re) { 284 alert("impossible: "+re.toString()); 285 } 286 var success = !this.state.failed; 287 this.input.rewind(start); 288 <@stop()> 289 this.state.backtracking--; 290 this.state.failed=false; 291 return success; 292} 293>> 294 295lexerSynpred(name) ::= << 296<synpred(name)> 297>> 298 299ruleMemoization(name) ::= << 300<if(memoize)> 301if ( this.state.backtracking>0 && this.alreadyParsedRule(this.input, <ruleDescriptor.index>) ) { return <ruleReturnValue()>; } 302<endif> 303>> 304 305/** How to test for failure and return from rule */ 306checkRuleBacktrackFailure() ::= << 307<if(backtracking)>if (this.state.failed) return <ruleReturnValue()>;<endif> 308>> 309 310/** This rule has failed, exit indicating failure during backtrack */ 311ruleBacktrackFailure() ::= << 312<if(backtracking)>if (this.state.backtracking>0) {this.state.failed=true; return <ruleReturnValue()>;}<endif> 313>> 314 315/** How to generate code for a rule. This includes any return type 316 * data aggregates required for multiple return values. 317 */ 318rule(ruleName,ruleDescriptor,block,emptyRule,description,exceptions,finally,memoize) ::= << 319<ruleAttributeScope(scope=ruleDescriptor.ruleScope)> 320<returnScope(scope=ruleDescriptor.returnScope)> 321 322// <fileName>:<description> 323// $ANTLR start "<ruleName>" 324<ruleDescriptor.actions.decorate> 325<ruleName>: function(<ruleDescriptor.parameterScope:parameterScope(scope=it)>) { 326 <if(trace)>this.traceIn("<ruleName>", <ruleDescriptor.index>);<endif> 327 <ruleScopeSetUp()> 328 <ruleDeclarations()> 329 <ruleLabelDefs()> 330 <ruleDescriptor.actions.init> 331 <@preamble()> 332 try { 333 <ruleMemoization(name=ruleName)> 334 <block> 335 <ruleCleanUp()> 336 <(ruleDescriptor.actions.after):execAction()> 337 } 338<if(exceptions)> 339 <exceptions:{e|<catch(decl=e.decl,action=e.action)><\n>}> 340<else> 341<if(!emptyRule)> 342<if(actions.(actionScope).rulecatch)> 343 <actions.(actionScope).rulecatch> 344<else> 345 catch (re) { 346 if (re instanceof org.antlr.runtime.RecognitionException) { 347 this.reportError(re); 348 this.recover(this.input,re); 349 <@setErrorReturnValue()> 350 } else { 351 throw re; 352 } 353 }<\n> 354<endif> 355<endif> 356<endif> 357 finally { 358 <if(trace)>this.traceOut("<ruleName>", <ruleDescriptor.index>);<endif> 359 <memoize()> 360 <ruleScopeCleanUp()> 361 <finally> 362 } 363 <@postamble()> 364 return <ruleReturnValue()>; 365} 366>> 367 368catch(decl,action) ::= << 369catch (<e.decl>) { 370 <e.action> 371} 372>> 373 374ruleDeclarations() ::= << 375<if(ruleDescriptor.hasMultipleReturnValues)> 376var retval = new <returnType()>(); 377retval.start = this.input.LT(1);<\n> 378<else> 379<ruleDescriptor.returnScope.attributes:{ a | 380var <a.name> = <if(a.initValue)><a.initValue><else>null<endif>; 381}> 382<endif> 383<if(memoize)> 384var <ruleDescriptor.name>_StartIndex = this.input.index(); 385<endif> 386>> 387 388ruleScopeSetUp() ::= << 389<ruleDescriptor.useScopes:{this.<it>_stack.push({});}; separator="\n"> 390<ruleDescriptor.ruleScope:{this.<it.name>_stack.push({});}; separator="\n"> 391>> 392 393ruleScopeCleanUp() ::= << 394<ruleDescriptor.useScopes:{this.<it>_stack.pop();}; separator="\n"> 395<ruleDescriptor.ruleScope:{this.<it.name>_stack.pop();}; separator="\n"> 396>> 397 398ruleLabelDefs() ::= << 399<[ruleDescriptor.tokenLabels,ruleDescriptor.tokenListLabels] 400 :{var <it.label.text> = null;}; separator="\n" 401> 402<[ruleDescriptor.tokenListLabels,ruleDescriptor.ruleListLabels] 403 :{var list_<it.label.text>=null;}; separator="\n" 404> 405<ruleDescriptor.ruleLabels:ruleLabelDef(label=it); separator="\n"> 406<ruleDescriptor.ruleListLabels:{ll|var <ll.label.text> = null;}; separator="\n"> 407>> 408 409lexerRuleLabelDefs() ::= << 410<[ruleDescriptor.tokenLabels, 411 ruleDescriptor.tokenListLabels, 412 ruleDescriptor.ruleLabels] 413 :{var <it.label.text>=null;}; separator="\n" 414> 415<ruleDescriptor.charLabels:{var <it.label.text>;}; separator="\n"> 416<[ruleDescriptor.tokenListLabels, 417 ruleDescriptor.ruleListLabels, 418 ruleDescriptor.ruleListLabels] 419 :{var list_<it.label.text>=null;}; separator="\n" 420> 421>> 422 423ruleReturnValue() ::= << 424<if(!ruleDescriptor.isSynPred)> 425<if(ruleDescriptor.hasReturnValue)> 426<if(ruleDescriptor.hasSingleReturnValue)> 427<ruleDescriptor.singleValueReturnName> 428<else> 429retval 430<endif> 431<endif> 432<endif> 433>> 434 435ruleCleanUp() ::= << 436<if(ruleDescriptor.hasMultipleReturnValues)> 437<if(!TREE_PARSER)> 438retval.stop = this.input.LT(-1);<\n> 439<endif> 440<endif> 441>> 442 443memoize() ::= << 444<if(memoize)> 445<if(backtracking)> 446if ( this.state.backtracking>0 ) { this.memoize(this.input, <ruleDescriptor.index>, <ruleDescriptor.name>_StartIndex); } 447<endif> 448<endif> 449>> 450 451/** How to generate a rule in the lexer; naked blocks are used for 452 * fragment rules. 453 */ 454lexerRule(ruleName,nakedBlock,ruleDescriptor,block,memoize) ::= << 455// $ANTLR start <ruleName> 456m<ruleName>: function(<ruleDescriptor.parameterScope:parameterScope(scope=it)>) { 457 <if(trace)>this.traceIn("<ruleName>", <ruleDescriptor.index>);<endif> 458 <ruleScopeSetUp()> 459 <ruleDeclarations()> 460 try { 461<if(nakedBlock)> 462 <ruleMemoization(name=ruleName)> 463 <lexerRuleLabelDefs()> 464 <ruleDescriptor.actions.init> 465 <block><\n> 466<else> 467 var _type = this.<ruleName>; 468 var _channel = org.antlr.runtime.BaseRecognizer.DEFAULT_TOKEN_CHANNEL; 469 <ruleMemoization(name=ruleName)> 470 <lexerRuleLabelDefs()> 471 <ruleDescriptor.actions.init> 472 <block> 473 <ruleCleanUp()> 474 this.state.type = _type; 475 this.state.channel = _channel; 476 <(ruleDescriptor.actions.after):execAction()> 477<endif> 478 } 479 finally { 480 <if(trace)>this.traceOut("<ruleName>", <ruleDescriptor.index>);<endif> 481 <ruleScopeCleanUp()> 482 <memoize()> 483 } 484}, 485// $ANTLR end "<ruleName>" 486>> 487 488/** How to generate code for the implicitly-defined lexer grammar rule 489 * that chooses between lexer rules. 490 */ 491tokensRule(ruleName,nakedBlock,args,block,ruleDescriptor) ::= << 492mTokens: function() { 493 <block><\n> 494} 495>> 496 497// S U B R U L E S 498 499/** A (...) subrule with multiple alternatives */ 500block(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= << 501// <fileName>:<description> 502var alt<decisionNumber>=<maxAlt>; 503<decls> 504<@predecision()> 505<decision> 506<@postdecision()> 507<@prebranch()> 508switch (alt<decisionNumber>) { 509 <alts:altSwitchCase()> 510} 511<@postbranch()> 512>> 513 514/** A rule block with multiple alternatives */ 515ruleBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= << 516// <fileName>:<description> 517var alt<decisionNumber>=<maxAlt>; 518<decls> 519<@predecision()> 520<decision> 521<@postdecision()> 522switch (alt<decisionNumber>) { 523 <alts:altSwitchCase()> 524} 525>> 526 527ruleBlockSingleAlt(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,description) ::= << 528// <fileName>:<description> 529<decls> 530<@prealt()> 531<alts> 532<@postalt()> 533>> 534 535/** A special case of a (...) subrule with a single alternative */ 536blockSingleAlt(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,description) ::= << 537// <fileName>:<description> 538<decls> 539<@prealt()> 540<alts> 541<@postalt()> 542>> 543 544/** A (..)+ block with 1 or more alternatives */ 545positiveClosureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= << 546// <fileName>:<description> 547var cnt<decisionNumber>=0; 548<decls> 549<@preloop()> 550loop<decisionNumber>: 551do { 552 var alt<decisionNumber>=<maxAlt>; 553 <@predecision()> 554 <decision> 555 <@postdecision()> 556 switch (alt<decisionNumber>) { 557 <alts:altSwitchCase()> 558 default : 559 if ( cnt<decisionNumber> >= 1 ) { 560 break loop<decisionNumber>; 561 } 562 <ruleBacktrackFailure()> 563 var eee = new org.antlr.runtime.EarlyExitException(<decisionNumber>, this.input); 564 <@earlyExitException()> 565 throw eee; 566 } 567 cnt<decisionNumber>++; 568} while (true); 569<@postloop()> 570>> 571 572positiveClosureBlockSingleAlt ::= positiveClosureBlock 573 574/** A (..)* block with 1 or more alternatives */ 575closureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= << 576// <fileName>:<description> 577<decls> 578<@preloop()> 579loop<decisionNumber>: 580do { 581 var alt<decisionNumber>=<maxAlt>; 582 <@predecision()> 583 <decision> 584 <@postdecision()> 585 switch (alt<decisionNumber>) { 586 <alts:altSwitchCase()> 587 default : 588 break loop<decisionNumber>; 589 } 590} while (true); 591<@postloop()> 592>> 593 594closureBlockSingleAlt ::= closureBlock 595 596/** Optional blocks (x)? are translated to (x|) by before code generation 597 * so we can just use the normal block template 598 */ 599optionalBlock ::= block 600 601optionalBlockSingleAlt ::= block 602 603/** A case in a switch that jumps to an alternative given the alternative 604 * number. A DFA predicts the alternative and then a simple switch 605 * does the jump to the code that actually matches that alternative. 606 */ 607altSwitchCase() ::= << 608case <i> : 609 <@prealt()> 610 <it> 611 break;<\n> 612>> 613 614/** An alternative is just a list of elements; at outermost level */ 615alt(elements,altNum,description,autoAST,outerAlt,treeLevel,rew) ::= << 616// <fileName>:<description> 617<! (function() { /* @todo4 (do we really need a new scope?) */ !> 618<@declarations()> 619<elements:element()> 620<rew> 621<@cleanup()> 622<! }).call(this); !> 623>> 624 625/** What to emit when there is no rewrite. For auto build 626 * mode, does nothing. 627 */ 628noRewrite(rewriteBlockLevel, treeLevel) ::= "" 629 630// E L E M E N T S 631 632/** Dump the elements one per line */ 633element() ::= << 634<@prematch()> 635<it.el><\n> 636>> 637 638/** match a token optionally with a label in front */ 639tokenRef(token,label,elementIndex,terminalOptions) ::= << 640<if(label)><label>=<endif>this.match(this.input,<token>,<grammar.recognizerName>.FOLLOW_<token>_in_<ruleName><elementIndex>); <checkRuleBacktrackFailure()> 641>> 642 643/** ids+=ID */ 644tokenRefAndListLabel(token,label,elementIndex,terminalOptions) ::= << 645<tokenRef(...)> 646<listLabel(elem=label,...)> 647>> 648 649listLabel(label,elem) ::= << 650if (org.antlr.lang.isNull(list_<label>)) list_<label> = []; 651list_<label>.push(<elem>);<\n> 652>> 653 654/** match a character */ 655charRef(char,label) ::= << 656<if(label)> 657<label> = this.input.LA(1);<\n> 658<endif> 659this.match(<char>); <checkRuleBacktrackFailure()> 660>> 661 662/** match a character range */ 663charRangeRef(a,b,label) ::= << 664<if(label)> 665<label> = this.input.LA(1);<\n> 666<endif> 667this.matchRange(<a>,<b>); <checkRuleBacktrackFailure()> 668>> 669 670/** For now, sets are interval tests and must be tested inline */ 671matchSet(s,label,elementIndex,postmatchCode="") ::= << 672<if(label)> 673<if(LEXER)> 674<label>= this.input.LA(1);<\n> 675<else> 676<label>=this.input.LT(1);<\n> 677<endif> 678<endif> 679if ( <s> ) { 680 this.input.consume(); 681 <postmatchCode> 682<if(!LEXER)> 683 this.state.errorRecovery=false; 684<endif> 685 <if(backtracking)>this.state.failed=false;<endif> 686} 687else { 688 <ruleBacktrackFailure()> 689 var mse = new org.antlr.runtime.MismatchedSetException(null,this.input); 690 <@mismatchedSetException()> 691<if(LEXER)> 692 this.recover(mse); 693 throw mse; 694<else> 695 throw mse; 696 <! use following code to make it recover inline; remove throw mse; 697 this.recoverFromMismatchedSet(this.input,mse,<grammar.recognizerName>.FOLLOW_set_in_<ruleName><elementIndex>); 698 !> 699<endif> 700}<\n> 701>> 702 703matchRuleBlockSet ::= matchSet 704 705matchSetAndListLabel(s,label,elementIndex,postmatchCode) ::= << 706<matchSet(...)> 707<listLabel(elem=label,...)> 708>> 709 710/** Match a string literal */ 711lexerStringRef(string,label,elementIndex) ::= << 712<if(label)> 713var <label>Start = this.getCharIndex(); 714this.match(<string>); <checkRuleBacktrackFailure()> 715var <label> = new org.antlr.runtime.CommonToken(this.input, org.antlr.runtime.Token.INVALID_TOKEN_TYPE, org.antlr.runtime.Token.DEFAULT_CHANNEL, <label>Start, this.getCharIndex()-1); 716<else> 717this.match(<string>); <checkRuleBacktrackFailure()><\n> 718<endif> 719>> 720 721wildcard(label,elementIndex) ::= << 722<if(label)> 723<label>=this.input.LT(1);<\n> 724<endif> 725this.matchAny(this.input); <checkRuleBacktrackFailure()> 726>> 727 728wildcardAndListLabel(label,elementIndex) ::= << 729<wildcard(...)> 730<listLabel(elem=label,...)> 731>> 732 733/** Match . wildcard in lexer */ 734wildcardChar(label, elementIndex) ::= << 735<if(label)> 736<label> = this.input.LA(1);<\n> 737<endif> 738this.matchAny(); <checkRuleBacktrackFailure()> 739>> 740 741wildcardCharListLabel(label, elementIndex) ::= << 742<wildcardChar(...)> 743<listLabel(elem=label,...)> 744>> 745 746// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 747/** Match a rule reference by invoking it possibly with arguments 748 * and a return value or values. 749 */ 750ruleRef(rule,label,elementIndex,args,scope) ::= << 751this.pushFollow(<grammar.recognizerName>.FOLLOW_<rule.name>_in_<ruleName><elementIndex>); 752<if(label)><label>=<endif>this.<if(scope)><scope:delegateName()>.<endif><rule.name>(<args; separator=", ">);<\n> 753this.state._fsp--; 754<checkRuleBacktrackFailure()> 755>> 756 757/** ids+=r */ 758ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= << 759<ruleRef(...)> 760<listLabel(elem=label,...)> 761>> 762 763/** A lexer rule reference */ 764lexerRuleRef(rule,label,args,elementIndex,scope) ::= << 765<if(label)> 766var <label>Start<elementIndex> = this.getCharIndex(); 767this.<if(scope)><scope:delegateName()>.<endif>m<rule.name>(<args; separator=", ">); <checkRuleBacktrackFailure()> 768<label> = new org.antlr.runtime.CommonToken(this.input, org.antlr.runtime.Token.INVALID_TOKEN_TYPE, org.antlr.runtime.Token.DEFAULT_CHANNEL, <label>Start<elementIndex>, this.getCharIndex()-1); 769<else> 770this.<if(scope)><scope:delegateName()>.<endif>m<rule.name>(<args; separator=", ">); <checkRuleBacktrackFailure()> 771<endif> 772>> 773 774/** i+=INT in lexer */ 775lexerRuleRefAndListLabel(rule,label,args,elementIndex,scope) ::= << 776<lexerRuleRef(...)> 777<listLabel(elem=label,...)> 778>> 779 780/** EOF in the lexer */ 781lexerMatchEOF(label,elementIndex) ::= << 782<if(label)> 783var <label>Start<elementIndex> = this.getCharIndex(); 784this.match(EOF); <checkRuleBacktrackFailure()> 785var <label> = new org.antlr.runtime.CommonToken(this.input, this.EOF, org.antlr.runtime.Token.DEFAULT_CHANNEL, <label>Start<elementIndex>, this.getCharIndex()-1); 786<else> 787this.match(this.EOF); <checkRuleBacktrackFailure()> 788<endif> 789>> 790 791// used for left-recursive rules 792recRuleDefArg() ::= "int <recRuleArg()>" 793recRuleArg() ::= "_p" 794recRuleAltPredicate(ruleName,opPrec) ::= "<recRuleArg()> \<= <opPrec>" 795recRuleSetResultAction() ::= "root_0=$<ruleName>_primary.tree;" 796recRuleSetReturnAction(src,name) ::= "$<name>=$<src>.<name>;" 797 798/** match ^(root children) in tree parser */ 799tree(root, actionsAfterRoot, children, nullableChildList,enclosingTreeLevel, treeLevel) ::= << 800<root:element()> 801<actionsAfterRoot:element()> 802<if(nullableChildList)> 803if ( this.input.LA(1)==org.antlr.runtime.Token.DOWN ) { 804 this.match(this.input, org.antlr.runtime.Token.DOWN, null); <checkRuleBacktrackFailure()> 805 <children:element()> 806 this.match(this.input, org.antlr.runtime.Token.UP, null); <checkRuleBacktrackFailure()> 807} 808<else> 809this.match(this.input, org.antlr.runtime.Token.DOWN, null); <checkRuleBacktrackFailure()> 810<children:element()> 811this.match(this.input, org.antlr.runtime.Token.UP, null); <checkRuleBacktrackFailure()> 812<endif> 813>> 814 815/** Every predicate is used as a validating predicate (even when it is 816 * also hoisted into a prediction expression). 817 */ 818validateSemanticPredicate(pred,description) ::= << 819if ( !(<evalPredicate(...)>) ) { 820 <ruleBacktrackFailure()> 821 throw new org.antlr.runtime.FailedPredicateException(this.input, "<ruleName>", "<description>"); 822} 823>> 824 825// F i x e d D F A (if-then-else) 826 827dfaState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= << 828var LA<decisionNumber>_<stateNumber> = this.input.LA(<k>);<\n> 829<edges; separator="\nelse "> 830else { 831<if(eotPredictsAlt)> 832 alt<decisionNumber>=<eotPredictsAlt>; 833<else> 834 <ruleBacktrackFailure()> 835 var nvae = 836 new org.antlr.runtime.NoViableAltException("<description>", <decisionNumber>, <stateNumber>, this.input);<\n> 837 <@noViableAltException()> 838 throw nvae;<\n> 839<endif> 840} 841>> 842 843/** Same as a normal DFA state except that we don't examine lookahead 844 * for the bypass alternative. It delays error detection but this 845 * is faster, smaller, and more what people expect. For (X)? people 846 * expect "if ( LA(1)==X ) match(X);" and that's it. 847 */ 848dfaOptionalBlockState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= << 849var LA<decisionNumber>_<stateNumber> = this.input.LA(<k>);<\n> 850<edges; separator="\nelse "> 851>> 852 853/** A DFA state that is actually the loopback decision of a closure 854 * loop. If end-of-token (EOT) predicts any of the targets then it 855 * should act like a default clause (i.e., no error can be generated). 856 * This is used only in the lexer so that for ('a')* on the end of a rule 857 * anything other than 'a' predicts exiting. 858 */ 859dfaLoopbackState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= << 860var LA<decisionNumber>_<stateNumber> = this.input.LA(<k>);<\n> 861<edges; separator="\nelse "><\n> 862<if(eotPredictsAlt)> 863<if(!edges)> 864alt<decisionNumber>=<eotPredictsAlt>; <! if no edges, don't gen ELSE !> 865<else> 866else { 867 alt<decisionNumber>=<eotPredictsAlt>; 868}<\n> 869<endif> 870<endif> 871>> 872 873/** An accept state indicates a unique alternative has been predicted */ 874dfaAcceptState(alt) ::= "alt<decisionNumber>=<alt>;" 875 876/** A simple edge with an expression. If the expression is satisfied, 877 * enter to the target state. To handle gated productions, we may 878 * have to evaluate some predicates for this edge. 879 */ 880dfaEdge(labelExpr, targetState, predicates) ::= << 881if ( (<labelExpr>) <if(predicates)>&& (<predicates>)<endif>) { 882 <targetState> 883} 884>> 885 886// F i x e d D F A (switch case) 887 888/** A DFA state where a SWITCH may be generated. The code generator 889 * decides if this is possible: CodeGenerator.canGenerateSwitch(). 890 */ 891dfaStateSwitch(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= << 892switch ( this.input.LA(<k>) ) { 893<edges; separator="\n"> 894default: 895<if(eotPredictsAlt)> 896 alt<decisionNumber>=<eotPredictsAlt>; 897<else> 898 <ruleBacktrackFailure()> 899 var nvae = 900 new org.antlr.runtime.NoViableAltException("<description>", <decisionNumber>, <stateNumber>, this.input);<\n> 901 <@noViableAltException()> 902 throw nvae;<\n> 903<endif> 904}<\n> 905>> 906 907dfaOptionalBlockStateSwitch(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= << 908switch ( this.input.LA(<k>) ) { 909 <edges; separator="\n"> 910}<\n> 911>> 912 913dfaLoopbackStateSwitch(k, edges,eotPredictsAlt,description,stateNumber,semPredState) ::= << 914switch ( this.input.LA(<k>) ) { 915<edges; separator="\n"><\n> 916<if(eotPredictsAlt)> 917default: 918 alt<decisionNumber>=<eotPredictsAlt>; 919 break;<\n> 920<endif> 921}<\n> 922>> 923 924dfaEdgeSwitch(labels, targetState) ::= << 925<labels:{case <it>:}; separator="\n"> 926 <targetState> 927 break; 928>> 929 930// C y c l i c D F A 931 932/** The code to initiate execution of a cyclic DFA; this is used 933 * in the rule to predict an alt just like the fixed DFA case. 934 * The <name> attribute is inherited via the parser, lexer, ... 935 */ 936dfaDecision(decisionNumber,description) ::= << 937alt<decisionNumber> = this.dfa<decisionNumber>.predict(this.input); 938>> 939 940/* Dump DFA tables as run-length-encoded Strings of octal values. 941 * Can't use hex as compiler translates them before compilation. 942 * These strings are split into multiple, concatenated strings. 943 * Java puts them back together at compile time thankfully. 944 * Java cannot handle large static arrays, so we're stuck with this 945 * encode/decode approach. See analysis and runtime DFA for 946 * the encoding methods. 947 */ 948cyclicDFA(dfa) ::= << 949org.antlr.lang.augmentObject(<grammar.recognizerName>, { 950 DFA<dfa.decisionNumber>_eotS: 951 "<dfa.javaCompressedEOT; wrap="\"+\n \"">", 952 DFA<dfa.decisionNumber>_eofS: 953 "<dfa.javaCompressedEOF; wrap="\"+\n \"">", 954 DFA<dfa.decisionNumber>_minS: 955 "<dfa.javaCompressedMin; wrap="\"+\n \"">", 956 DFA<dfa.decisionNumber>_maxS: 957 "<dfa.javaCompressedMax; wrap="\"+\n \"">", 958 DFA<dfa.decisionNumber>_acceptS: 959 "<dfa.javaCompressedAccept; wrap="\"+\n \"">", 960 DFA<dfa.decisionNumber>_specialS: 961 "<dfa.javaCompressedSpecial; wrap="\"+\n \"">}>", 962 DFA<dfa.decisionNumber>_transitionS: [ 963 <dfa.javaCompressedTransition:{s|"<s; wrap="\"+\n\"">"}; separator=",\n"> 964 ] 965}); 966 967org.antlr.lang.augmentObject(<grammar.recognizerName>, { 968 DFA<dfa.decisionNumber>_eot: 969 org.antlr.runtime.DFA.unpackEncodedString(<grammar.recognizerName>.DFA<dfa.decisionNumber>_eotS), 970 DFA<dfa.decisionNumber>_eof: 971 org.antlr.runtime.DFA.unpackEncodedString(<grammar.recognizerName>.DFA<dfa.decisionNumber>_eofS), 972 DFA<dfa.decisionNumber>_min: 973 org.antlr.runtime.DFA.unpackEncodedStringToUnsignedChars(<grammar.recognizerName>.DFA<dfa.decisionNumber>_minS), 974 DFA<dfa.decisionNumber>_max: 975 org.antlr.runtime.DFA.unpackEncodedStringToUnsignedChars(<grammar.recognizerName>.DFA<dfa.decisionNumber>_maxS), 976 DFA<dfa.decisionNumber>_accept: 977 org.antlr.runtime.DFA.unpackEncodedString(<grammar.recognizerName>.DFA<dfa.decisionNumber>_acceptS), 978 DFA<dfa.decisionNumber>_special: 979 org.antlr.runtime.DFA.unpackEncodedString(<grammar.recognizerName>.DFA<dfa.decisionNumber>_specialS), 980 DFA<dfa.decisionNumber>_transition: (function() { 981 var a = [], 982 i, 983 numStates = <grammar.recognizerName>.DFA<dfa.decisionNumber>_transitionS.length; 984 for (i=0; i\<numStates; i++) { 985 a.push(org.antlr.runtime.DFA.unpackEncodedString(<grammar.recognizerName>.DFA<dfa.decisionNumber>_transitionS[i])); 986 } 987 return a; 988 })() 989}); 990 991<grammar.recognizerName>.DFA<dfa.decisionNumber> = function(recognizer) { 992 this.recognizer = recognizer; 993 this.decisionNumber = <dfa.decisionNumber>; 994 this.eot = <grammar.recognizerName>.DFA<dfa.decisionNumber>_eot; 995 this.eof = <grammar.recognizerName>.DFA<dfa.decisionNumber>_eof; 996 this.min = <grammar.recognizerName>.DFA<dfa.decisionNumber>_min; 997 this.max = <grammar.recognizerName>.DFA<dfa.decisionNumber>_max; 998 this.accept = <grammar.recognizerName>.DFA<dfa.decisionNumber>_accept; 999 this.special = <grammar.recognizerName>.DFA<dfa.decisionNumber>_special; 1000 this.transition = <grammar.recognizerName>.DFA<dfa.decisionNumber>_transition; 1001}; 1002 1003org.antlr.lang.extend(<grammar.recognizerName>.DFA<dfa.decisionNumber>, org.antlr.runtime.DFA, { 1004 getDescription: function() { 1005 return "<dfa.description>"; 1006 }, 1007 <@errorMethod()> 1008<if(dfa.specialStateSTs)> 1009 specialStateTransition: function(s, input) { 1010 var _s = s; 1011 /* bind to recognizer so semantic predicates can be evaluated */ 1012 var retval = (function(s, input) { 1013 switch ( s ) { 1014 <dfa.specialStateSTs:{state | 1015 case <i0> : <! compressed special state numbers 0..n-1 !> 1016 <state>}; separator="\n"> 1017 } 1018 }).call(this.recognizer, s, input); 1019 if (!org.antlr.lang.isUndefined(retval)) { 1020 return retval; 1021 } 1022<if(backtracking)> 1023 if (this.recognizer.state.backtracking>0) {this.recognizer.state.failed=true; return -1;}<\n> 1024<endif> 1025 var nvae = 1026 new org.antlr.runtime.NoViableAltException(this.getDescription(), <dfa.decisionNumber>, _s, input); 1027 this.error(nvae); 1028 throw nvae; 1029 },<\n> 1030<endif> 1031 dummy: null 1032});<\n> 1033>> 1034 1035/** A state in a cyclic DFA; it's a special state and part of a big switch on 1036 * state. 1037 */ 1038cyclicDFAState(decisionNumber,stateNumber,edges,needErrorClause,semPredState) ::= << 1039var LA<decisionNumber>_<stateNumber> = input.LA(1);<\n> 1040<if(semPredState)> <! get next lookahead symbol to test edges, then rewind !> 1041var index<decisionNumber>_<stateNumber> = input.index(); 1042input.rewind();<\n> 1043<endif> 1044s = -1; 1045<edges; separator="\nelse "> 1046<if(semPredState)> <! return input cursor to state before we rewound !> 1047input.seek(index<decisionNumber>_<stateNumber>);<\n> 1048<endif> 1049if ( s>=0 ) return s; 1050break; 1051>> 1052 1053/** Just like a fixed DFA edge, test the lookahead and indicate what 1054 * state to jump to next if successful. 1055 */ 1056cyclicDFAEdge(labelExpr, targetStateNumber, edgeNumber, predicates) ::= << 1057if ( (<labelExpr>) <if(predicates)>&& (<predicates>)<endif>) {s = <targetStateNumber>;}<\n> 1058>> 1059 1060/** An edge pointing at end-of-token; essentially matches any char; 1061 * always jump to the target. 1062 */ 1063eotDFAEdge(targetStateNumber,edgeNumber, predicates) ::= << 1064s = <targetStateNumber>;<\n> 1065>> 1066 1067 1068// D F A E X P R E S S I O N S 1069 1070andPredicates(left,right) ::= "(<left>&&<right>)" 1071 1072orPredicates(operands) ::= "(<first(operands)><rest(operands):{o | ||<o>}>)" 1073 1074notPredicate(pred) ::= "!(<evalPredicate(...)>)" 1075 1076evalPredicate(pred,description) ::= "(<pred>)" 1077 1078evalSynPredicate(pred,description) ::= "this.<pred>()" 1079 1080lookaheadTest(atom,k,atomAsInt) ::= "LA<decisionNumber>_<stateNumber>==<atom>" 1081 1082/** Sometimes a lookahead test cannot assume that LA(k) is in a temp variable 1083 * somewhere. Must ask for the lookahead directly. 1084 */ 1085isolatedLookaheadTest(atom,k,atomAsInt) ::= "this.input.LA(<k>)==<atom>" 1086 1087lookaheadRangeTest(lower,upper,k,rangeNumber,lowerAsInt,upperAsInt) ::= << 1088(LA<decisionNumber>_<stateNumber>\>=<lower> && LA<decisionNumber>_<stateNumber>\<=<upper>) 1089>> 1090 1091isolatedLookaheadRangeTest(lower,upper,k,rangeNumber,lowerAsInt,upperAsInt) ::= "(this.input.LA(<k>)\>=<lower> && this.input.LA(<k>)\<=<upper>)" 1092 1093setTest(ranges) ::= "<ranges; separator=\"||\">" 1094 1095// A T T R I B U T E S 1096 1097globalAttributeScope(scope) ::= << 1098<if(scope.attributes)> 1099<scope.name>_stack: [],<\n> 1100<endif> 1101>> 1102 1103ruleAttributeScope(scope) ::= << 1104<if(scope.attributes)> 1105<scope.name>_stack: [],<\n> 1106<endif> 1107>> 1108 1109returnStructName() ::= "<it.name>_return" 1110 1111returnType() ::= << 1112<if(ruleDescriptor.hasMultipleReturnValues)> 1113<ruleDescriptor.grammar.recognizerName>.<ruleDescriptor:returnStructName()> 1114<else> 1115<if(ruleDescriptor.hasSingleReturnValue)> 1116<ruleDescriptor.singleValueReturnType> 1117<else> 1118void 1119<endif> 1120<endif> 1121>> 1122 1123/** Generate the Java type associated with a single or multiple return 1124 * values. 1125 */ 1126ruleLabelType(referencedRule) ::= << 1127<if(referencedRule.hasMultipleReturnValues)> 1128<referencedRule.grammar.recognizerName>.<referencedRule.name>_return 1129<else> 1130<if(referencedRule.hasSingleReturnValue)> 1131<referencedRule.singleValueReturnType> 1132<else> 1133void 1134<endif> 1135<endif> 1136>> 1137 1138delegateName() ::= << 1139<if(it.label)><it.label><else>g<it.name><endif> 1140>> 1141 1142/** Using a type to init value map, try to init a type; if not in table 1143 * must be an object, default value is "null". 1144 */ 1145initValue(typeName) ::= << 1146null 1147>> 1148 1149/** Define a rule label including default value */ 1150ruleLabelDef(label) ::= << 1151<!<ruleLabelType(referencedRule=label.referencedRule)>!> var <label.label.text> = <initValue(typeName=ruleLabelType(referencedRule=label.referencedRule))>; 1152>> 1153 1154/** Define a return struct for a rule if the code needs to access its 1155 * start/stop tokens, tree stuff, attributes, ... Leave a hole for 1156 * subgroups to stick in members. 1157 */ 1158returnScope(scope) ::= << 1159<if(ruleDescriptor.hasMultipleReturnValues)> 1160// inline static return class 1161<ruleDescriptor:returnStructName()>: (function() { 1162 <returnType()> = function(){}; 1163 org.antlr.lang.extend(<returnType()>, 1164 org.antlr.runtime.<if(TREE_PARSER)>tree.Tree<else>Parser<endif>RuleReturnScope, 1165 { 1166 <@ruleReturnMembers()> 1167 }); 1168 return; 1169})(), 1170<endif> 1171>> 1172 1173parameterScope(scope) ::= << 1174<scope.attributes:{<it.decl>}; separator=", "> 1175>> 1176 1177parameterAttributeRef(attr) ::= "<attr.name>" 1178parameterSetAttributeRef(attr,expr) ::= "<attr.name> =<expr>;" 1179 1180scopeAttributeRef(scope,attr,index,negIndex) ::= << 1181<if(negIndex)> 1182(this.<scope>_stack[this.<scope>_stack.length-<negIndex>-1]).<attr.name> 1183<else> 1184<if(index)> 1185(this.<scope>_stack[<index>]).<attr.name> 1186<else> 1187org.antlr.lang.array.peek(this.<scope>_stack).<attr.name> 1188<endif> 1189<endif> 1190>> 1191 1192scopeSetAttributeRef(scope,attr,expr,index,negIndex) ::= << 1193<if(negIndex)> 1194(this.<scope>_stack[this.<scope>_stack.length-<negIndex>-1]).<attr.name> =<expr>; 1195<else> 1196<if(index)> 1197(this.<scope>_stack[<index>]).<attr.name> =<expr>; 1198<else> 1199org.antlr.lang.array.peek(this.<scope>_stack).<attr.name> =<expr>; 1200<endif> 1201<endif> 1202>> 1203 1204/** $x is either global scope or x is rule with dynamic scope; refers 1205 * to stack itself not top of stack. This is useful for predicates 1206 * like {$function.size()>0 && $function::name.equals("foo")}? 1207 */ 1208isolatedDynamicScopeRef(scope) ::= "this.<scope>_stack" 1209 1210/** reference an attribute of rule; might only have single return value */ 1211ruleLabelRef(referencedRule,scope,attr) ::= << 1212<if(referencedRule.hasMultipleReturnValues)> 1213(<scope>!==null?<scope>.<attr.name>:<initValue(attr.type)>) 1214<else> 1215<scope> 1216<endif> 1217>> 1218 1219returnAttributeRef(ruleDescriptor,attr) ::= << 1220<if(ruleDescriptor.hasMultipleReturnValues)> 1221retval.<attr.name> 1222<else> 1223<attr.name> 1224<endif> 1225>> 1226 1227returnSetAttributeRef(ruleDescriptor,attr,expr) ::= << 1228<if(ruleDescriptor.hasMultipleReturnValues)> 1229retval.<attr.name> =<expr>; 1230<else> 1231<attr.name> =<expr>; 1232<endif> 1233>> 1234 1235/** How to translate $tokenLabel */ 1236tokenLabelRef(label) ::= "<label>" 1237 1238/** ids+=ID {$ids} or e+=expr {$e} */ 1239listLabelRef(label) ::= "list_<label>" 1240 1241 1242// not sure the next are the right approach 1243 1244tokenLabelPropertyRef_text(scope,attr) ::= "(<scope>?<scope>.getText():null)" 1245tokenLabelPropertyRef_type(scope,attr) ::= "(<scope>?<scope>.getType():0)" 1246tokenLabelPropertyRef_line(scope,attr) ::= "(<scope>?<scope>.getLine():0)" 1247tokenLabelPropertyRef_pos(scope,attr) ::= "(<scope>?<scope>.getCharPositionInLine():0)" 1248tokenLabelPropertyRef_channel(scope,attr) ::= "(<scope>?<scope>.getChannel():0)" 1249tokenLabelPropertyRef_index(scope,attr) ::= "(<scope>?<scope>.getTokenIndex():0)" 1250tokenLabelPropertyRef_tree(scope,attr) ::= "<scope>_tree" 1251tokenLabelPropertyRef_int(scope,attr) ::= "(<scope>?parseInt(<scope>.getText(), 10):0)" 1252 1253ruleLabelPropertyRef_start(scope,attr) ::= "(<scope>?<scope>.start:null)" 1254ruleLabelPropertyRef_stop(scope,attr) ::= "(<scope>?<scope>.stop:null)" 1255ruleLabelPropertyRef_tree(scope,attr) ::= "(<scope>?<scope>.tree:null)" 1256ruleLabelPropertyRef_text(scope,attr) ::= << 1257<if(TREE_PARSER)> 1258(<scope>?(this.input.getTokenStream().toString( 1259 this.input.getTreeAdaptor().getTokenStartIndex(<scope>.start), 1260 this.input.getTreeAdaptor().getTokenStopIndex(<scope>.start))):null) 1261<else> 1262(<scope>?this.input.toString(<scope>.start,<scope>.stop):null) 1263<endif> 1264>> 1265 1266ruleLabelPropertyRef_st(scope,attr) ::= "<scope>.st" 1267 1268/** Isolated $RULE ref ok in lexer as it's a Token */ 1269lexerRuleLabel(label) ::= "<label>" 1270 1271lexerRuleLabelPropertyRef_type(scope,attr) ::= "(<scope>?<scope>.getType():0)" 1272lexerRuleLabelPropertyRef_line(scope,attr) ::= "(<scope>?<scope>.getLine():0)" 1273lexerRuleLabelPropertyRef_pos(scope,attr) ::= "(<scope>?<scope>.getCharPositionInLine():-1)" 1274lexerRuleLabelPropertyRef_channel(scope,attr) ::= "(<scope>?<scope>.getChannel():0)" 1275lexerRuleLabelPropertyRef_index(scope,attr) ::= "(<scope>?<scope>.getTokenIndex():0)" 1276lexerRuleLabelPropertyRef_text(scope,attr) ::= "(<scope>?<scope>.getText():0)" 1277 1278// Somebody may ref $template or $tree or $stop within a rule: 1279rulePropertyRef_start(scope,attr) ::= "(retval.start)" 1280rulePropertyRef_stop(scope,attr) ::= "(retval.stop)" 1281rulePropertyRef_tree(scope,attr) ::= "(retval.tree)" 1282rulePropertyRef_text(scope,attr) ::= << 1283<if(TREE_PARSER)> 1284this.input.getTokenStream().toString( 1285 this.input.getTreeAdaptor().getTokenStartIndex(retval.start), 1286 this.input.getTreeAdaptor().getTokenStopIndex(retval.start)) 1287<else> 1288this.input.toString(retval.start,this.input.LT(-1)) 1289<endif> 1290>> 1291rulePropertyRef_st(scope,attr) ::= "retval.st" 1292 1293lexerRulePropertyRef_text(scope,attr) ::= "this.getText()" 1294lexerRulePropertyRef_type(scope,attr) ::= "_type" 1295lexerRulePropertyRef_line(scope,attr) ::= "this.state.tokenStartLine" 1296lexerRulePropertyRef_pos(scope,attr) ::= "this.state.tokenStartCharPositionInLine" 1297lexerRulePropertyRef_index(scope,attr) ::= "-1" // undefined token index in lexer 1298lexerRulePropertyRef_channel(scope,attr) ::= "_channel" 1299lexerRulePropertyRef_start(scope,attr) ::= "this.state.tokenStartCharIndex" 1300lexerRulePropertyRef_stop(scope,attr) ::= "(this.getCharIndex()-1)" 1301lexerRulePropertyRef_int(scope,attr) ::= "parseInt(<scope>.getText(),10)" 1302 1303// setting $st and $tree is allowed in local rule. everything else 1304// is flagged as error 1305ruleSetPropertyRef_tree(scope,attr,expr) ::= "retval.tree =<expr>;" 1306ruleSetPropertyRef_st(scope,attr,expr) ::= "retval.st =<expr>;" 1307 1308 1309/** How to execute an action */ 1310execAction(action) ::= << 1311<if(backtracking)> 1312if ( <actions.(actionScope).synpredgate> ) { 1313 <action> 1314} 1315<else> 1316<action> 1317<endif> 1318>> 1319 1320/** How to always execute an action even when backtracking */ 1321execForcedAction(action) ::= "<action>" 1322 1323// M I S C (properties, etc...) 1324 1325bitset(name, words64) ::= << 1326<! @todo overflow issue !> 1327<name>: new org.antlr.runtime.BitSet([<words64:{<it>};separator=",">]) 1328>> 1329 1330codeFileExtension() ::= ".js" 1331 1332true() ::= "true" 1333false() ::= "false" 1334