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