blob: dbba0ff9c7e38c1de990adde6e4394187723805d [file] [log] [blame]
/*
[The "BSD license"]
Copyright (c) 2006, 2007 Kay Roepke 2010 Alan Condit
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Template group file for the Objective C code generator.
* Heavily based on Java.stg
*
* Written by Kay Roepke <kroepke(at)classdump.org>
* Modified by Alan Condit <acondit(at)ipns.com>
*
* This file is part of ANTLR and subject to the same license as ANTLR itself.
*/
objcTypeInitMap ::= [
"int" : "0", // Integers start out being 0
"long" : "0", // Longs start out being 0
"float" : "0.0", // Floats start out being 0
"double" : "0.0", // Doubles start out being 0
"BOOL" : "NO", // Booleans start out being Antlr ObjC for false
"byte" : "0", // Bytes start out being 0
"short" : "0", // Shorts start out being 0
"char" : "0", // Chars start out being 0
"id" : "nil", // ids start out being nil
default : "nil" // anything other than an atomic type
]
className() ::= "<name><!<if(LEXER)>Lexer<else><if(TREE_PARSER)>Tree<endif>Parser<endif>!>"
leadIn(type) ::=
<<
/** \file
* This <type> file was generated by $ANTLR version <ANTLRVersion>
*
* - From the grammar source file : <fileName>
* - On : <generatedTimestamp>
<if(LEXER)>
* - for the lexer : <name>Lexer
<endif>
<if(PARSER)>
* - for the parser : <name>Parser
<endif>
<if(TREE_PARSER)>
* - for the tree parser : <name>TreeParser
<endif>
*
* Editing it, at least manually, is not wise.
*
* ObjC language generator and runtime by Alan Condit, acondit|hereisanat|ipns|dotgoeshere|com.
*
*
>>
/** The overall file structure of a recognizer; stores methods for rules
* and cyclic DFAs plus support code.
*/
outputFile( LEXER,
PARSER,
TREE_PARSER,
actionScope,
actions,
docComment,
recognizer,
name,
tokens,
tokenNames,
rules,
cyclicDFAs,
bitsets,
buildTemplate,
buildAST,
rewriteMode,
profile,
backtracking,
synpreds,
memoize,
numRules,
fileName,
ANTLRVersion,
generatedTimestamp,
trace,
scopes,
superClass,
literals
) ::=
<<
<leadIn("OBJC source")>
*/
// $ANTLR <ANTLRVersion> <fileName> <generatedTimestamp>
<! <if(actions.(actionScope).header)>
/* =============================================================================
* This is what the grammar programmer asked us to put at the top of every file.
*/
<actions.(actionScope).header>
/* End of Header action.
* =============================================================================
*/
<endif> !>
/* -----------------------------------------
* Include the ANTLR3 generated header file.
*/
#import "<name><!<if(LEXER)>Lexer<else><if(TREE_PARSER)>Tree<endif>Parser<endif>!>.h"
<actions.(actionScope).postinclude>
/* ----------------------------------------- */
<docComment>
<if(literals)>
/** String literals used by <name> that we must do things like MATCHS() with.
* C will normally just lay down 8 bit characters, and you can use L"xxx" to
* get wchar_t, but wchar_t is 16 bits on Windows, which is not UTF32 and so
* we perform this little trick of defining the literals as arrays of UINT32
* and passing in the address of these.
*/
<literals:{it | static ANTLR3_UCHAR lit_<i>[] = <it>;}; separator="\n">
<endif>
/* ============================================================================= */
/* =============================================================================
* Start of recognizer
*/
<recognizer>
>>
headerFileExtension() ::= ".h"
headerFile( LEXER,
PARSER,
TREE_PARSER,
actionScope,
actions,
docComment,
recognizer,
name,
tokens,
tokenNames,
rules,
cyclicDFAs,
bitsets,
buildTemplate,
buildAST,
rewriteMode,
profile,
backtracking,
synpreds,
memoize,
numRules,
fileName,
ANTLRVersion,
generatedTimestamp,
trace,
scopes,
superClass,
literals
) ::=
<<
// $ANTLR <ANTLRVersion> <fileName> <generatedTimestamp>
<@imports>
<actions.(actionScope).preincludes>
/* =============================================================================
* Standard antlr3 OBJC runtime definitions
*/
#import \<Foundation/Foundation.h>
#import \<ANTLR/ANTLR.h>
/* End of standard antlr3 runtime definitions
* =============================================================================
*/
<actions.(actionScope).includes>
<@end>
<if(LEXER)>
<lexerHeaderFile(...)>
<endif>
<if(PARSER)>
<parserHeaderFile(...)>
<endif>
<if(TREE_PARSER)>
<treeParserHeaderFile(...)>
<endif>
<docComment>
>>
lexerHeaderFile( LEXER,
PARSER,
TREE_PARSER,
actionScope,
actions,
docComment,
recognizer,
name,
tokens,
tokenNames,
rules,
cyclicDFAs,
bitsets,
buildTemplate,
profile,
backtracking,
synpreds,
memoize,
numRules,
fileName,
ANTLRVersion,
generatedTimestamp,
trace,
scopes,
superClass="ANTLRLexer"
) ::=
<<
<if(actions.(actionScope).header)>
/* =============================================================================
* This is what the grammar programmer asked us to put at the top of every file.
*/
<actions.(actionScope).header>
/* End of Header action.
* =============================================================================
*/
<endif>
/* Start cyclicDFAInterface */
<cyclicDFAs:cyclicDFAInterface()>
#pragma mark Rule return scopes Interface start
<rules:{rule |
<rule.ruleDescriptor:{ruleDescriptor | <returnScopeInterface(scope=ruleDescriptor.returnScope)>}>}>
#pragma mark Rule return scopes Interface end
#pragma mark Tokens
#ifdef EOF
#undef EOF
#endif
<tokens:{it | #define <it.name> <it.type>}; separator="\n">
/* interface lexer class */
@interface <className()> <@superClassName>: <superClass><@end> { // line 283
<cyclicDFAs:{dfa | DFA<dfa.decisionNumber> *dfa<dfa.decisionNumber>;}; separator="\n">
<synpreds:{pred | SEL <pred>Selector;}; separator="\n">
/* ObjC start of actions.lexer.memVars */
<actions.lexer.memVars>
/* ObjC end of actions.lexer.memVars */
}
+ (void) initialize;
+ (<className()> *)new<className()>WithCharStream:(id\<ANTLRCharStream>)anInput;
/* ObjC start actions.lexer.methodsDecl */
<actions.lexer.methodsDecl>
/* ObjC end actions.lexer.methodsDecl */
<rules:{rule |
- (<rule.ruleDescriptor:{ruleDescriptor|<returnType()>}>) <if(!rule.ruleDescriptor.isSynPred)>m<rule.ruleName><else><rule.ruleName>_fragment<endif> <if(rule.ruleDescriptor.parameterScope)><rule.ruleDescriptor.parameterScope:parameterScope()><endif>; }; separator="\n"><\n>
@end /* end of <className()> interface */<\n>
>>
headerReturnScope(ruleDescriptor) ::= "<returnScopeInterface(...)>"
headerReturnType(ruleDescriptor) ::= <<
<if(LEXER)>
<if(!r.ruleDescriptor.isSynPred)>
void
<else>
<ruleDescriptor:returnType()>
<endif>
<else>
<ruleDescriptor:returnType()>
<endif>
>>
// Produce the lexer output
lexer( grammar,
name,
tokens,
scopes,
rules,
numRules,
filterMode,
labelType="ANTLRCommonToken",
superClass="ANTLRLexer"
) ::= <<
<cyclicDFAs:cyclicDFA()>
/** As per Terence: No returns for lexer rules! */
<!
#pragma mark Rule return scopes start
<rules:{rule | <rule.ruleDescriptor:{ruleDescriptor |
<returnScopeImplementation(scope=ruleDescriptor.returnScope)>}>
}>
#pragma mark Rule return scopes end
!>
@implementation <grammar.recognizerName> // line 330
+ (void) initialize
{
[ANTLRBaseRecognizer setGrammarFileName:@"<fileName>"];
}
+ (NSString *) tokenNameForType:(NSInteger)aTokenType
{
return [[self getTokenNames] objectAtIndex:aTokenType];
}
+ (<grammar.recognizerName> *)new<grammar.recognizerName>WithCharStream:(id\<ANTLRCharStream>)anInput
{
return [[<grammar.recognizerName> alloc] initWithCharStream:anInput];
}
- (id) initWithCharStream:(id\<ANTLRCharStream>)anInput
{
self = [super initWithCharStream:anInput State:[ANTLRRecognizerSharedState newANTLRRecognizerSharedStateWithRuleLen:<numRules>+1]];
if ( self != nil ) {
<if(memoize)>
if ( state.ruleMemo == nil ) {
state.ruleMemo = [[ANTLRRuleStack newANTLRRuleStackWithSize:<numRules>+1] retain];
}
if ( [state.ruleMemo count] == 0 ) {
// initialize the memoization cache - the indices are 1-based in the runtime code!
<! [state.ruleMemo addObject:[NSNull null]]; /* dummy entry to ensure 1-basedness. */ !>
for (NSInteger i = 0; i \< <numRules>; i++) {
[state.ruleMemo addObject:[ANTLRHashRule newANTLRHashRuleWithLen:17]];
}
}
<endif>
<synpreds:{pred | <lexerSynpred(name=pred)>};separator="\n">
<cyclicDFAs:{dfa | dfa<dfa.decisionNumber> = [DFA<dfa.decisionNumber> newDFA<dfa.decisionNumber>WithRecognizer:self];}; separator="\n">
<actions.lexer.init>
}
return self;
}
- (void) dealloc
{
<cyclicDFAs:{dfa | [dfa<dfa.decisionNumber> release];}; separator="\n">
<actions.lexer.dealloc>
[super dealloc];
}
/* ObjC Start of actions.lexer.methods */
<actions.lexer.methods>
/* ObjC end of actions.lexer.methods */
/* ObjC start methods() */
<@methods()>
/* ObjC end methods() */
<if(actions.lexer.reset)>
- (void) reset
{
<actions.lexer.reset>
[super reset];
}
<endif>
<if(filterMode)>
<filteringNextToken()>
<endif>
/* Start of Rules */
<rules; separator="\n">
@end /* end of <grammar.recognizerName> implementation line 397 */
>>
/** A override of Lexer.nextToken() that backtracks over mTokens() looking
* for matches. No error can be generated upon error; just rewind, consume
* a token and then try again. backtracking needs to be set as well.
* Make rule memoization happen only at levels above 1 as we start mTokens
* at backtracking==1.
*/
filteringNextToken() ::= <<
- (id\<ANTLRToken>) nextToken
{
while (YES) {
if ( [input LA:1] == ANTLRCharStreamEOF ) {
return [<labelType> eofToken];
}
state.token = nil;
state.channel = ANTLRTokenChannelDefault;
state.tokenStartCharIndex = input.index;
state.tokenStartCharPositionInLine = input.charPositionInLine;
state.tokenStartLine = input.line;
state.text = nil;
@try {
NSInteger m = [input mark];
state.backtracking = 1; /* means we won't throw slow exception */
state.failed = NO;
[self mTokens];
state.backtracking = 0;
/* mTokens backtracks with synpred at backtracking==2
and we set the synpredgate to allow actions at level 1. */
if ( state.failed ) {
[input rewind:m];
[input consume]; /* advance one char and try again */
} else {
[self emit];
return state.token;
}
}
@catch (ANTLRRecognitionException *re) {
// shouldn't happen in backtracking mode, but...
[self reportError:re];
[self recover:re];
}
}
}
- (void)memoize:(id\<ANTLRIntStream\>)anInput
RuleIndex:(NSInteger)ruleIndex
StartIndex:(NSInteger)ruleStartIndex
{
if ( state.backtracking > 1 ) [super memoize:anInput RuleIndex:ruleIndex StartIndex:ruleStartIndex];
}
- (BOOL)alreadyParsedRule:(id\<ANTLRIntStream\>)anInput RuleIndex:(NSInteger)ruleIndex
{
if ( state.backtracking > 1 ) return [super alreadyParsedRule:anInput RuleIndex:ruleIndex];
return NO;
}
>>
actionGate() ::= "state.backtracking == 0"
filteringActionGate() ::= "state.backtracking == 1"
parserHeaderFile( LEXER,
PARSER,
TREE_PARSER,
actionScope,
actions,
docComment,
recognizer,
name,
tokens,
tokenNames,
rules,
cyclicDFAs,
bitsets,
buildTemplate,
profile,
backtracking,
synpreds,
memoize,
numRules,
fileName,
ANTLRVersion,
generatedTimestamp,
trace,
scopes,
literals,
superClass="ANTLRParser"
) ::= <<
/* parserHeaderFile */
<genericParserHeaderFile(inputStreamType="id\<ANTLRTokenStream>",...)>
>>
treeParserHeaderFile( LEXER,
PARSER,
TREE_PARSER,
actionScope,
actions,
docComment,
recognizer,
name,
tokens,
tokenNames,
rules,
cyclicDFAs,
bitsets,
buildTemplate,
profile,
backtracking,
synpreds,
memoize,
numRules,
fileName,
ANTLRVersion,
generatedTimestamp,
trace,
scopes,
literals,
superClass="ANTLRTreeParser"
) ::= <<
/* treeParserHeaderFile */
<genericParserHeaderFile(inputStreamType="id\<ANTLRTreeNodeStream>",...)>
>>
genericParserHeaderFile( LEXER,
PARSER,
TREE_PARSER,
actionScope,
actions,
docComment,
recognizer,
name,
tokens,
tokenNames,
rules,
cyclicDFAs,
bitsets,
buildTemplate,
profile,
backtracking,
synpreds,
memoize,
numRules,
fileName,
ANTLRVersion,
generatedTimestamp,
trace,
scopes,
superClass,
literals,
inputStreamType
) ::=
<<
<if(actions.(actionScope).header)>
/* =============================================================================
* This is what the grammar programmer asked us to put at the top of every file.
*/
<actions.(actionScope).header>
/* End of Header action.
* =============================================================================
*/
<endif>
#ifndef ANTLR3TokenTypeAlreadyDefined
#define ANTLR3TokenTypeAlreadyDefined
typedef enum {
ANTLR_EOF = -1,
INVALID,
EOR,
DOWN,
UP,
MIN
} ANTLR3TokenType;
#endif
<cyclicDFAs:cyclicDFAInterface()>
#pragma mark Tokens
#ifdef EOF
#undef EOF
#endif
<tokens:{it | #define <it.name> <it.type>}; separator="\n">
#pragma mark Dynamic Global Scopes globalAttributeScopeInterface
<scopes:{it | <if(it.isDynamicGlobalScope)><globalAttributeScopeInterface(scope=it)><endif>}>
#pragma mark Dynamic Rule Scopes ruleAttributeScopeInterface
<rules:{rule |
<rule.ruleDescriptor:{ ruleDescriptor | <ruleAttributeScopeInterface(scope=ruleDescriptor.ruleScope)>}>}>
#pragma mark Rule Return Scopes returnScopeInterface
<rules:{rule |<rule.ruleDescriptor:{ ruleDescriptor | <returnScopeInterface(scope=ruleDescriptor.returnScope)>}>}>
/* Interface grammar class */
@interface <className()> <@superClassName> : <superClass><@end> { /* line 572 */
#pragma mark Dynamic Rule Scopes ruleAttributeScopeDecl
<rules:{rule | <rule.ruleDescriptor.ruleScope:ruleAttributeScopeDecl(scope=rule.ruleDescriptor.ruleScope)>}>
#pragma mark Dynamic Global Rule Scopes globalAttributeScopeMemVar
<scopes:{it | <if(it.isDynamicGlobalScope)><globalAttributeScopeMemVar(scope=it)><endif>}><\n>
/* ObjC start of actions.(actionScope).memVars */
<actions.(actionScope).memVars>
/* ObjC end of actions.(actionScope).memVars */
/* ObjC start of memVars */
<@memVars()>
/* ObjC end of memVars */
<cyclicDFAs:{dfa | DFA<dfa.decisionNumber> *dfa<dfa.decisionNumber>;}; separator="\n">
<synpreds:{pred | SEL <pred>Selector;}; separator="\n">
}
/* ObjC start of actions.(actionScope).properties */
<actions.(actionScope).properties>
/* ObjC end of actions.(actionScope).properties */
/* ObjC start of properties */
<@properties()>
/* ObjC end of properties */
+ (void) initialize;
+ (id) new<className()>:(<inputStreamType>)aStream;
/* ObjC start of actions.(actionScope).methodsDecl */
<actions.(actionScope).methodsDecl>
/* ObjC end of actions.(actionScope).methodsDecl */
/* ObjC start of methodsDecl */
<@methodsDecl()>
/* ObjC end of methodsDecl */
<rules:{rule |
- (<rule.ruleDescriptor:{ruleDescriptor|<returnType()>}>)<if(!rule.ruleDescriptor.isSynPred)><rule.ruleName><else><rule.ruleName>_fragment<endif><if(rule.ruleDescriptor.parameterScope)><rule.ruleDescriptor.parameterScope:parameterScope()><endif>; }; separator="\n"><\n>
@end /* end of <className()> interface */<\n>
>>
parser( grammar,
name,
scopes,
tokens,
tokenNames,
rules,
numRules,
bitsets,
ASTLabelType="ANTLRCommonTree",
superClass="ANTLRParser",
labelType="ANTLRCommonToken",
members={<actions.parser.members>}
) ::= <<
<genericParser(inputStreamType="id\<ANTLRTokenStream>", rewriteElementType="Token", ...)>
>>
/** How to generate a tree parser; same as parser except the input
* stream is a different type.
*/
treeParser( grammar,
name,
scopes,
tokens,
tokenNames,
globalAction,
rules,
numRules,
bitsets,
filterMode,
labelType={<ASTLabelType>},
ASTLabelType="ANTLRCommonTree",
superClass={<if(filterMode)><if(buildAST)>ANTLRTreeRewriter<else>ANTLRTreeFilter<endif><else>ANTLRTreeParser<endif>},
members={<actions.treeparser.members>}
) ::= <<
<genericParser(inputStreamType="id\<ANTLRTreeNodeStream>", rewriteElementType="Node", ...)>
>>
/** How to generate a parser */
genericParser( grammar,
name,
scopes,
tokens,
tokenNames,
rules,
numRules,
cyclicDFAs, // parser init -- initializes the DFAs
bitsets,
labelType,
ASTLabelType,
superClass,
members,
filterMode,
rewriteElementType,
inputStreamType
) ::= <<
<cyclicDFAs:cyclicDFA()>
#pragma mark Bitsets
<bitsets:{it | <bitset(name={FOLLOW_<it.name>_in_<it.inName><it.tokenIndex>}, words64=it.bits)>}>
#pragma mark Dynamic Global globalAttributeScopeImplementation
<scopes:{it | <if(it.isDynamicGlobalScope)><globalAttributeScopeImplementation(scope=it)><endif>}>
#pragma mark Dynamic Rule Scopes ruleAttributeScopeImplementation
<rules:{rule |
<rule.ruleDescriptor:{ ruleDescriptor | <ruleAttributeScopeImplementation(scope=ruleDescriptor.ruleScope)>}>}>
#pragma mark Rule Return Scopes returnScopeImplementation
<rules:{rule | <rule.ruleDescriptor:{ ruleDescriptor | <returnScopeImplementation(scope=ruleDescriptor.returnScope)>}>}>
@implementation <grammar.recognizerName> // line 637
#pragma mark Dynamic Rule Scopes ruleAttributeScope
<rules:{rule | <rule.ruleDescriptor.ruleScope:ruleAttributeScope()>}>
#pragma mark global Attribute Scopes globalAttributeScope
<scopes:{it | <if(it.isDynamicGlobalScope)><globalAttributeScope()><endif>}>
/* ObjC start actions.(actionScope).synthesize */
<actions.(actionScope).synthesize>
/* ObjC start synthesize() */
<@synthesize()>
+ (void) initialize
{
#pragma mark Bitsets
<bitsets:{it | <bitsetInit(name={FOLLOW_<it.name>_in_<it.inName><it.tokenIndex>}, words64=it.bits)>}>
[ANTLRBaseRecognizer setTokenNames:[[AMutableArray arrayWithObjects:@"\<invalid>", @"\<EOR>", @"\<DOWN>", @"\<UP>", <tokenNames:{it | @<it>}; separator=", ", wrap="\n ">, nil] retain]];
[ANTLRBaseRecognizer setGrammarFileName:@"<fileName>"];
<synpreds:{pred | <synpred(pred)>}>
}
+ (<grammar.recognizerName> *)new<grammar.recognizerName>:(<inputStreamType>)aStream
{
<if(PARSER)>
return [[<grammar.recognizerName> alloc] initWithTokenStream:aStream];
<else><! TREE_PARSER !>
return [[<grammar.recognizerName> alloc] initWithStream:aStream];
<endif>
}
<if(PARSER)>
- (id) initWithTokenStream:(<inputStreamType>)aStream
{
self = [super initWithTokenStream:aStream State:[ANTLRRecognizerSharedState newANTLRRecognizerSharedStateWithRuleLen:<numRules>+1]];
if ( self != nil ) {
<else><! TREE_PARSER !>
- (id) initWithStream:(<inputStreamType>)aStream
{
self = [super initWithStream:aStream State:[[ANTLRRecognizerSharedState newANTLRRecognizerSharedStateWithRuleLen:<numRules>+1] retain]];
if ( self != nil ) {
<endif>
<! <parserCtorBody()> !>
<cyclicDFAs:{dfa | dfa<dfa.decisionNumber> = [DFA<dfa.decisionNumber> newDFA<dfa.decisionNumber>WithRecognizer:self];}; separator="\n">
<scopes:{it | <if(it.isDynamicGlobalScope)><globalAttributeScopeInit(scope=it)><endif>}>
<rules:{rule | <rule.ruleDescriptor.ruleScope:ruleAttributeScopeInit()>}>
/* start of actions-actionScope-init */
<actions.(actionScope).init>
/* start of init */
<@init()>
}
return self;
}
- (void) dealloc
{
<cyclicDFAs:{dfa | [dfa<dfa.decisionNumber> release];}; separator="\n">
<scopes:{it | <if(it.isDynamicGlobalScope)><globalAttributeScopeDealloc(scope=it)><endif>}>
<actions.(actionScope).dealloc>
<@dealloc()>
[super dealloc];
}
/* ObjC start actions.(actionScope).methods */
<actions.(actionScope).methods>
/* ObjC end actions.(actionScope).methods */
/* ObjC start methods() */
<@methods()>
/* ObjC end methods() */
/* ObjC start rules */
<rules; separator="\n">
/* ObjC end rules */
@end /* end of <grammar.recognizerName> implementation line 692 */<\n>
>>
parserCtorBody() ::= <<
<if(memoize)> /* parserCtorBody */
<if(grammar.grammarIsRoot)>
state.ruleMemo = [[ANTLRRuleStack newANTLRRuleStack:<numRules>+1] retain];<\n> <! index from 1..n !>
<endif>
<endif>
<grammar.delegators:
{g|this.<g:delegateName()> = <g:delegateName()>;}; separator="\n">
>>
/** A simpler version of a rule template that is specific to the imaginary
* rules created for syntactic predicates. As they never have return values
* nor parameters etc..., just give simplest possible method. Don't do
* any of the normal memoization stuff in here either; it's a waste.
* As predicates cannot be inlined into the invoking rule, they need to
* be in a rule by themselves.
*/
synpredRule(ruleName, ruleDescriptor, block, description, nakedBlock) ::=
<<
// $ANTLR start <ruleName>_fragment
- (void) <ruleName>_fragment
{
<ruleLabelDefs()>
<if(trace)>
[self traceIn:\@"<ruleName>_fragment" Index:<ruleDescriptor.index>];
@try {
<block>
}
@finally {
[self traceOut:\@"<ruleName>_fragment" Index:<ruleDescriptor.index>];
}
<else>
<block>
<endif>
} // $ANTLR end <ruleName>_fragment
>>
synpred(name) ::= <<
SEL <name>Selector = @selector(<name>_fragment);
<! // $ANTLR start <name>
- (BOOL) <name>
{
state.backtracking++;
<@start()>
NSInteger start = [input mark];
@try {
[self <name>_fragment]; // can never throw exception
}
@catch (ANTLRRecognitionException *re) {
NSLog(@"impossible: %@\n", re.name);
}
BOOL success = (state.failed == NO);
[input rewind:start];
<@stop()>
state.backtracking--;
state.failed=NO;
return success;
} // $ANTLR end <name> <\n> !>
>>
lexerSynpred(name) ::= <<
<synpred(name)>
>>
ruleMemoization(name) ::= <<
<if(memoize)>
if ( state.backtracking > 0 && [self alreadyParsedRule:input RuleIndex:<ruleDescriptor.index>] ) { return <ruleReturnValue()>; }
<endif>
>>
/** How to test for failure and return from rule */
checkRuleBacktrackFailure() ::= <<
<if (backtracking)>if ( state.failed ) return <ruleReturnValue()>;<endif>
>>
/** This rule has failed, exit indicating failure during backtrack */
ruleBacktrackFailure() ::= <<
<if(backtracking)>if ( state.backtracking > 0 ) { state.failed = YES; return <ruleReturnValue()>; }<\n><endif>
>>
/** How to generate code for a rule.
* The return type aggregates are declared in the header file (headerFile template)
*/
rule(ruleName,ruleDescriptor,block,emptyRule,description,exceptions,finally,memoize) ::= <<
/*
* $ANTLR start <ruleName>
* <fileName>:<description>
*/
- (<returnType()>) <ruleName><ruleDescriptor.parameterScope:parameterScope()>
{
<if(trace)>[self traceIn:\@"<ruleName>" Index:<ruleDescriptor.index>];<endif>
<if(trace)>NSLog(@"enter <ruleName> %@ failed=%@ backtracking=%d", [input LT:1], (state.failed==YES)?@"YES":@"NO", state.backtracking);<endif>
<ruleScopeSetUp()>
<ruleDeclarations()>
<ruleDescriptor.actions.init>
<@preamble()>
@try {
<ruleMemoization(name=ruleName)>
<ruleLabelDefs()>
<block>
<ruleCleanUp()>
<(ruleDescriptor.actions.after):execAction()>
}
<if(exceptions)>
<exceptions:{e|<catch(decl=e.decl,action=e.action)><\n>}>
<else><if(!emptyRule)><if(actions.(actionScope).rulecatch)>
<actions.(actionScope).rulecatch>
<else>
@catch (ANTLRRecognitionException *re) {
[self reportError:re];
[self recover:input Exception:re];
<@setErrorReturnValue()>
}<\n>
<endif><endif><endif>
@finally {
<if(trace)>[self traceOut:@"<ruleName>" Index:<ruleDescriptor.index>];<endif>
<memoize()>
<ruleScopeCleanUp()>
<finally>
}
<@postamble()>
return <ruleReturnValue()>;
}
/* $ANTLR end <ruleName> */
>>
finalCode(finalBlock) ::= <<
{
<finalBlock>
}
>>
catch(decl,action) ::= <<
@catch (<e.decl>) {
<e.action>
}
>>
ruleDeclarations() ::= <<
/* ruleDeclarations */
<if(ruleDescriptor.hasMultipleReturnValues)>
<returnType()> retval = [<ruleDescriptor:returnStructName()> new<ruleDescriptor:returnStructName()>];
[retval setStart:[input LT:1]];<\n>
<else>
<ruleDescriptor.returnScope.attributes:{ a |
<a.type> <a.name> = <if(a.initValue)><a.initValue><else><initValue(a.type)><endif>;
}>
<endif>
<if(memoize)>
NSInteger <ruleDescriptor.name>_StartIndex = input.index;
<endif>
>>
ruleScopeSetUp() ::= <<
/* ruleScopeSetUp */
<ruleDescriptor.useScopes:{it | [<it>_stack push:[<it>_Scope new<it>_Scope]];}>
<ruleDescriptor.ruleScope:{it | [<it.name>_stack push:[<it.name>_Scope new<it.name>_Scope]];}>
>>
ruleScopeCleanUp() ::= <<
/* ruleScopeCleanUp */
<ruleDescriptor.useScopes:{it | [<it>_stack pop];}; separator="\n">
<ruleDescriptor.ruleScope:{it | [<it.name>_stack pop];}; separator="\n">
>>
ruleLabelDefs() ::= <<
<[ruleDescriptor.tokenLabels, ruleDescriptor.tokenListLabels,
ruleDescriptor.wildcardTreeLabels,ruleDescriptor.wildcardTreeListLabels]
:{it | <labelType> *<it.label.text> = nil;}; separator="\n">
<[ruleDescriptor.tokenListLabels,ruleDescriptor.ruleListLabels,ruleDescriptor.wildcardTreeListLabels]
:{it | AMutableArray *list_<it.label.text> = nil;}; separator="\n"
>
<ruleDescriptor.ruleLabels:ruleLabelDef(); separator="\n">
<ruleDescriptor.ruleListLabels:{ll|ANTLRParserRuleReturnScope *<ll.label.text> = nil;}; separator="\n">
>>
lexerRuleLabelDefs() ::= <<
<[ruleDescriptor.tokenLabels,
ruleDescriptor.tokenListLabels,
ruleDescriptor.ruleLabels]
:{it | <labelType> *<it.label.text>=nil;}; separator="\n"
>
<ruleDescriptor.charLabels:{it | NSInteger <it.label.text>;}; separator="\n">
<[ruleDescriptor.tokenListLabels,
ruleDescriptor.ruleListLabels]:{it | AMutableArray *list_<it.label.text>=nil; }; separator="\n">
>>
ruleReturnValue() ::= <%
<if(!ruleDescriptor.isSynPred)>
<if(ruleDescriptor.hasReturnValue)>
<if(ruleDescriptor.hasSingleReturnValue)>
<ruleDescriptor.singleValueReturnName>
<else>
retval
<endif>
<endif>
<endif>
%>
ruleCleanUp() ::= <<
/* token+rule list labels */
<[ruleDescriptor.tokenListLabels,ruleDescriptor.ruleListLabels]:{it | [list_<it.label.text> release];}; separator="\n">
<if(ruleDescriptor.hasMultipleReturnValues)>
<if(!TREE_PARSER)>
[retval setStop:[input LT:-1]];<\n>
<endif><endif>
>>
memoize() ::= <<
<if(memoize)>
<if(backtracking)>
if (state.backtracking > 0) [self memoize:input RuleIndex:<ruleDescriptor.index> StartIndex:<ruleDescriptor.name>_StartIndex];
<endif><endif>
>>
/** How to generate a rule in the lexer; naked blocks are used for
* fragment rules.
*/
lexerRule(ruleName, nakedBlock, ruleDescriptor, block, memoize) ::= <<
// $ANTLR start "<ruleName>"
- (void) m<ruleName><if(ruleDescriptor.parameterScope)><ruleDescriptor.parameterScope:parameterScope(scope=it)><endif>
{
//<if(trace)>[self traceIn:\@"<ruleName>" Index:<ruleDescriptor.index>];<endif>
<if(trace)>NSLog(@"enter <ruleName> %C line=%d:%d failed=%@ backtracking=%d",
[input LA:1],
self.line,
self.charPositionInLine,
(state.failed==YES) ? @"YES" : @"NO",
state.backtracking);
<endif>
<ruleScopeSetUp()>
<ruleDeclarations()>
@try {
<if(nakedBlock)>
<ruleMemoization(name=ruleName)>
<lexerRuleLabelDefs()>
<ruleDescriptor.actions.init>
<block><\n>
<else>
NSInteger _type = <ruleName>;
NSInteger _channel = ANTLRTokenChannelDefault;
<ruleMemoization(name=ruleName)>
<lexerRuleLabelDefs()>
<ruleDescriptor.actions.init>
<block>
<ruleCleanUp()>
state.type = _type;
state.channel = _channel;
<(ruleDescriptor.actions.after):execAction()>
<endif>
}
@finally {
//<if(trace)>[self traceOut:[NSString stringWithFormat:@"<ruleName> %d\n", <ruleDescriptor.index>]];<endif>
<if(trace)>NSLog(@"exit <ruleName> %C line=%d:%d failed=%@ backtracking=%d",
[input LA:1], self.line, self.charPositionInLine,
(state.failed==YES) ? @"YES" : @"NO", state.backtracking);<endif>
<ruleScopeCleanUp()>
<memoize()>
}
return;
}
/* $ANTLR end "<ruleName>" */
>>
/** How to generate code for the implicitly-defined lexer grammar rule
* that chooses between lexer rules.
*/
tokensRule(ruleName,nakedBlock,args,block,ruleDescriptor) ::= <<
- (void) mTokens
{
<block><\n>
}
>>
// S U B R U L E S
/** A (...) subrule with multiple alternatives */
block(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
// <fileName>:<description> // block
NSInteger alt<decisionNumber>=<maxAlt>;
<decls>
<@predecision()>
<decision>
<@postdecision()>
<@prebranch()>
switch (alt<decisionNumber>) {
<alts:{a | <altSwitchCase(i, a)>}>
}
<@postbranch()>
>>
/** A rule block with multiple alternatives */
ruleBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
// <fileName>:<description> //ruleblock
NSInteger alt<decisionNumber>=<maxAlt>;
<decls>
<@predecision()>
<decision>
<@postdecision()>
switch (alt<decisionNumber>) {
<alts:{a | <altSwitchCase(i, a)>}>
}
>>
ruleBlockSingleAlt(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,description) ::= <<
// <fileName>:<description> // ruleBlockSingleAlt
<decls>
<@prealt()>
<alts>
<@postalt()>
>>
/** A special case of a (...) subrule with a single alternative */
blockSingleAlt(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,description) ::= <<
// <fileName>:<description> // blockSingleAlt
<decls>
<@prealt()>
<alts>
<@postalt()>
>>
/** A (..)+ block with 1 or more alternatives */
positiveClosureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
// <fileName>:<description> // positiveClosureBlock
NSInteger cnt<decisionNumber> = 0;
<decls>
<@preloop()>
do {
NSInteger alt<decisionNumber> = <maxAlt>;
<@predecision()>
<decision>
<@postdecision()>
switch (alt<decisionNumber>) {
<alts:{a | <altSwitchCase(i, a)>}>
default :
if ( cnt<decisionNumber> >= 1 )
goto loop<decisionNumber>;
<ruleBacktrackFailure()>
ANTLREarlyExitException *eee =
[ANTLREarlyExitException newException:input decisionNumber:<decisionNumber>];
<@earlyExitException()>
@throw eee;
}
cnt<decisionNumber>++;
} while (YES);
loop<decisionNumber>: ;
<@postloop()>
>>
positiveClosureBlockSingleAlt ::= positiveClosureBlock
/** A (..)* block with 0 or more alternatives */
closureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
<decls>
<@preloop()>
do {
NSInteger alt<decisionNumber>=<maxAlt>;
<@predecision()>
<decision>
<@postdecision()>
switch (alt<decisionNumber>) {
<alts:{a | <altSwitchCase(i, a)>}>
default :
goto loop<decisionNumber>;
}
} while (YES);
loop<decisionNumber>: ;
<@postloop()>
>>
closureBlockSingleAlt ::= closureBlock
/** Optional blocks (x)? are translated to (x|) by before code generation
* so we can just use the normal block template
*/
optionalBlock ::= block
optionalBlockSingleAlt ::= block
/** A case in a switch that jumps to an alternative given the alternative
* number. A DFA predicts the alternative and then a simple switch
* does the jump to the code that actually matches that alternative.
*/
altSwitchCase(altNum, alt) ::= <<
case <altNum> : ;
<@prealt()>
<alt>
break;<\n>
>>
/** An alternative is just a list of elements; at outermost level */
alt(elements,altNum,description,autoAST,outerAlt,treeLevel,rew) ::= <<
// <fileName>:<description> // alt
{
<@declarations()>
<elements:element()>
<rew>
<@cleanup()>
}
>>
/** What to emit when there is no rewrite. For auto build
* mode, does nothing.
*/
noRewrite(rewriteBlockLevel, treeLevel) ::= ""
// E L E M E N T S
/** Dump the elements one per line */
element(e) ::= << <@prematch()><\n><e.el><\n> >>
/** match a token optionally with a label in front */
tokenRef(token,label,elementIndex,terminalOptions) ::= <<
<if(label)><label>=(<labelType> *)<endif>[self match:input TokenType:<token> Follow:FOLLOW_<token>_in_<ruleName><elementIndex>]; <checkRuleBacktrackFailure()>
>>
/** ids+=ID */
tokenRefAndListLabel(token,label,elementIndex,terminalOptions) ::= <<
<tokenRef(...)>
<listLabel(elem=label,...)>
>>
listLabel(label,elem) ::= <<
if (list_<label> == nil) list_<label> = [[AMutableArray arrayWithCapacity:5] retain];
[list_<label> addObject:<elem>];<\n>
>>
/** match a character */
charRef(char,label) ::= <<
<if(label)>NSInteger <label> = [input LA:1];<\n><endif>
[self matchChar:<char>]; <checkRuleBacktrackFailure()><\n>
>>
/** match a character range */
charRangeRef(a,b,label) ::= <<
<if(label)><label> = [input LA:1];<\n><endif>
[self matchRangeFromChar:<a> to:<b>]; <checkRuleBacktrackFailure()>
>>
/** For now, sets are interval tests and must be tested inline */
matchSet(s,label,elementIndex,terminalOptions,postmatchCode="") ::= <<
<if(label)>
<if(LEXER)>
<label> = [input LA:1];<\n>
<else>
<label> = (<labelType> *)[input LT:1]; /* matchSet */<\n>
<endif><endif>
if (<s>) {
[input consume];
<postmatchCode>
<if(!LEXER)>
[state setIsErrorRecovery:NO];
<endif>
<if(backtracking)>state.failed = NO;<\n><endif>
} else {
<ruleBacktrackFailure()>
ANTLRMismatchedSetException *mse = [ANTLRMismatchedSetException newException:nil stream:input];
<@mismatchedSetException()>
<if(LEXER)>
<if(label)>
mse.c = <label>;
<endif>
[self recover:mse];
@throw mse;
<else>
@throw mse;
<! use following code to make it recover inline; remove throw mse;
[self recoverFromMismatchedSet:input exception:mse follow:FOLLOW_set_in_<ruleName><elementIndex>]; !>
<endif>
}<\n>
>>
matchRuleBlockSet ::= matchSet
matchSetAndListLabel(s,label,elementIndex,postmatchCode) ::= <<
<matchSet(...)>
<listLabel(elem=label,...)>
>>
/** Match a string literal */
lexerStringRef(string,label,elementIndex="0") ::= <<
<if(label)>
NSInteger <label>Start = input.index;
[self matchString:<string>]; <checkRuleBacktrackFailure()>
NSInteger StartLine<elementIndex> = self.line;
NSInteger <label>StartCharPos<elementIndex> = self.charPositionInLine;
<label> = [[<labelType> newToken:input Type:ANTLRTokenTypeInvalid Channel:ANTLRTokenChannelDefault Start:<label>Start Stop:input.index] retain];
[self setLine:<label>StartLine<elementIndex>];
[self setCharPositionInLine:<label>StartCharPos<elementIndex>];
<else>
[self matchString:<string>]; <checkRuleBacktrackFailure()><\n>
<endif>
>>
wildcard(token,label,elementIndex,terminalOptions) ::= <<
<if(label)>
<label> = (<labelType> *)[input LT:1];<\n>
<endif>
[self matchAny:input]; <checkRuleBacktrackFailure()>
>>
wildcardAndListLabel(token,label,elementIndex,terminalOptions) ::= <<
<wildcard(...)>
<listLabel(elem=label,...)>
>>
/** Match . wildcard in lexer */
wildcardChar(label, elementIndex) ::= <<
<if(label)>
NSInteger <label> = [input LA:1];<\n>
<endif>
[self matchAny]; <checkRuleBacktrackFailure()><\n>
>>
wildcardCharListLabel(label, elementIndex) ::= <<
<wildcardChar(...)>
<listLabel(elem=label,...)>
>>
/** Match a rule reference by invoking it possibly with arguments
* and a return value or values. The 'rule' argument was the
* target rule name, but now is type Rule, whose toString is
* same: the rule name. Now though you can access full rule
* descriptor stuff.
*/
ruleRef(rule,label,elementIndex,args,scope) ::= <<
/* ruleRef */
[self pushFollow:FOLLOW_<rule.name>_in_<ruleName><elementIndex>];
<if(label)><label> = <endif>[self <if(scope)><scope:delegateName()>.<endif><rule.name><if(args)>:<first(args)> <rest(args):{ a | arg<i>:<rest(args)>}; separator=" "><endif>];<\n>
[self popFollow];
<checkRuleBacktrackFailure()><\n>
>>
/** ids+=r */
ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
<ruleRef(...)>
<listLabel(elem=label,...)>
>>
/** A lexer rule reference.
*
* The 'rule' argument was the target rule name, but now
* is type Rule, whose toString is same: the rule name.
* Now though you can access full rule descriptor stuff.
*/
lexerRuleRef(rule,label,args,elementIndex,scope) ::= <<
<if(label)>
NSInteger <label>Start<elementIndex> = input.index;
[self m<rule.name><if(args)>:<args; separator=" :"><endif>]; <checkRuleBacktrackFailure()><\n>
<label> = [[<labelType> newToken:input Type:ANTLRTokenTypeInvalid Channel:ANTLRTokenChannelDefault Start:<label>Start<elementIndex> Stop:input.index-1] retain];
<label>.line = self.line;
<else>
[self <if(scope)><scope:delegateName()>.<endif>m<rule.name><if(args)>:<args; separator=" :"><endif>]; <checkRuleBacktrackFailure()><\n>
<endif>
>>
/** i+=INT in lexer */
lexerRuleRefAndListLabel(rule,label,args,elementIndex,scope) ::= <<
<lexerRuleRef(...)>
<listLabel(elem=label,...)>
>>
/** EOF in the lexer */
lexerMatchEOF(label,elementIndex) ::= <<
<if(label)>
NSInteger <label>Start<elementIndex> = input.index;
[self matchChar:ANTLRCharStreamEOF]; <checkRuleBacktrackFailure()><\n>
<labelType> <label> = [[<labelType> newToken:input Type:ANTLRTokenTypeEOF Channel:ANTLRTokenChannelDefault Start:<label>Start<elementIndex> Stop:input.index-1] retain];
<label>.line = self.line;
<else>
[self matchChar:ANTLRCharStreamEOF]; <checkRuleBacktrackFailure()><\n>
<endif>
>>
// used for left-recursive rules
recRuleDefArg() ::= "int <recRuleArg()>"
recRuleArg() ::= "_p"
recRuleAltPredicate(ruleName,opPrec) ::= "<recRuleArg()> \<= <opPrec>"
recRuleSetResultAction() ::= "root_0=$<ruleName>_primary.tree;"
recRuleSetReturnAction(src,name) ::= "$<name>=$<src>.<name>;"
/** match ^(root children) in tree parser */
tree(root, actionsAfterRoot, children, nullableChildList, enclosingTreeLevel, treeLevel) ::= <<
<root:element()>
<actionsAfterRoot:element()>
<if(nullableChildList)>
if ( [input LA:1] == DOWN ) {
[self match:input TokenType:DOWN Follow:nil]; <checkRuleBacktrackFailure()>
<children:element()>
[self match:input TokenType:UP Follow:nil]; <checkRuleBacktrackFailure()>
}
<else>
[self match:input TokenType:DOWN Follow:nil]; <checkRuleBacktrackFailure()>
<children:element()>
[self match:input TokenType:UP Follow:nil]; <checkRuleBacktrackFailure()>
<endif>
>>
/** Every predicate is used as a validating predicate (even when it is
* also hoisted into a prediction expression).
*/
validateSemanticPredicate(pred,description) ::= <<
if ( !(<evalPredicate(...)>) ) {
<ruleBacktrackFailure()>
@throw [ANTLRFailedPredicateException newException:@"<ruleName>" predicate:@"<description>" stream:input];
}
>>
// F i x e d D F A (if-then-else)
dfaState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
NSInteger LA<decisionNumber>_<stateNumber> = [input LA:<k>];<\n>
<edges; separator="\nelse ">
else {
<if(eotPredictsAlt)>
alt<decisionNumber> = <eotPredictsAlt>;
<else>
<ruleBacktrackFailure()>
ANTLRNoViableAltException *nvae = [ANTLRNoViableAltException newException:<decisionNumber> state:<stateNumber> stream:input];
nvae.c = LA<decisionNumber>_<stateNumber>;
<@noViableAltException()>
@throw nvae;<\n>
<endif>
}
>>
/** Same as a normal DFA state except that we don't examine lookahead
* for the bypass alternative. It delays error detection but this
* is faster, smaller, and more what people expect. For (X)? people
* expect "if ( LA(1)==X ) match(X);" and that's it.
*/
dfaOptionalBlockState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
NSInteger LA<decisionNumber>_<stateNumber> = [input LA:<k>];<\n>
<edges; separator="\nelse ">
>>
/** A DFA state that is actually the loopback decision of a closure
* loop. If end-of-token (EOT) predicts any of the targets then it
* should act like a default clause (i.e., no error can be generated).
* This is used only in the lexer so that for ('a')* on the end of a rule
* anything other than 'a' predicts exiting.
*/
dfaLoopbackState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
NSInteger LA<decisionNumber>_<stateNumber> = [input LA:<k>];
<edges; separator="\nelse "><\n>
<if(eotPredictsAlt)>
<if(!edges)>
alt<decisionNumber>=<eotPredictsAlt>; <! if no edges, don't gen ELSE !>
<else>
else {
alt<decisionNumber> = <eotPredictsAlt>;
}<\n>
<endif><endif>
>>
/** An accept state indicates a unique alternative has been predicted */
dfaAcceptState(alt) ::= "alt<decisionNumber>=<alt>;"
/** A simple edge with an expression. If the expression is satisfied,
* enter to the target state. To handle gated productions, we may
* have to evaluate some predicates for this edge.
*/
dfaEdge(labelExpr, targetState, predicates) ::= <<
if ( (<labelExpr>) <if(predicates)>&& (<predicates>)<endif>) {
<targetState>
}
>>
// F i x e d D F A (switch case)
/** A DFA state where a SWITCH may be generated. The code generator
* decides if this is possible: CodeGenerator.canGenerateSwitch().
*/
dfaStateSwitch(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
unichar charLA<decisionNumber> = [input LA:<k>];
switch (charLA<decisionNumber>) {
<edges; separator="\n"><\n>
default: ;
<if(eotPredictsAlt)>
alt<decisionNumber> = <eotPredictsAlt>;
<else>
<ruleBacktrackFailure()>
ANTLRNoViableAltException *nvae = [ANTLRNoViableAltException newException:<decisionNumber> state:<stateNumber> stream:input];
nvae.c = charLA<decisionNumber>;
<@noViableAltException()>
@throw nvae;<\n>
<endif>
}<\n>
>>
dfaOptionalBlockStateSwitch(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
switch ([input LA:<k>]) { // dfaOptionalBlockStateSwitch
<edges; separator="\n"><\n>
}<\n>
>>
dfaLoopbackStateSwitch(k, edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
switch ([input LA:<k>]) { // dfaLoopbackStateSwitch
<edges; separator="\n"><\n>
<if(eotPredictsAlt)>
default:
alt<decisionNumber> = <eotPredictsAlt>;
break;<\n>
<endif>
}<\n>
>>
dfaEdgeSwitch(labels, targetState) ::= <<
<labels:{it | case <it>: ;}; separator="\n">
{
<targetState>
}
break;
>>
// C y c l i c D F A
/** The code to initiate execution of a cyclic DFA; this is used
* in the rule to predict an alt just like the fixed DFA case.
* The <name> attribute is inherited via the parser, lexer, ...
*/
dfaDecision(decisionNumber,description) ::= <<
alt<decisionNumber> = [dfa<decisionNumber> predict:input];
>>
/** Used in headerFile */
cyclicDFAInterface(dfa) ::= <<
#pragma mark Cyclic DFA interface start DFA<dfa.decisionNumber>
@interface DFA<dfa.decisionNumber> : ANTLRDFA {
}
+ newDFA<dfa.decisionNumber>WithRecognizer:(ANTLRBaseRecognizer *)theRecognizer;
- initWithRecognizer:(ANTLRBaseRecognizer *)recognizer;
@end /* end of DFA<dfa.decisionNumber> interface */<\n>
#pragma mark Cyclic DFA interface end DFA<dfa.decisionNumber><\n>
>>
/** Used in lexer/parser implementation files */
/* Dump DFA tables as run-length-encoded Strings of octal values.
* Can't use hex as compiler translates them before compilation.
* These strings are split into multiple, concatenated strings.
* Java puts them back together at compile time thankfully.
* Java cannot handle large static arrays, so we're stuck with this
* encode/decode approach. See analysis and runtime DFA for
* the encoding methods.
*/
cyclicDFA(dfa) ::= <<
#pragma mark Cyclic DFA implementation start DFA<dfa.decisionNumber>
@implementation DFA<dfa.decisionNumber>
const static NSInteger dfa<dfa.decisionNumber>_eot[<dfa.numberOfStates>] =
{<dfa.eot; wrap="\n ", separator=",", null="-1">};
const static NSInteger dfa<dfa.decisionNumber>_eof[<dfa.numberOfStates>] =
{<dfa.eof; wrap="\n ", separator=",", null="-1">};
const static unichar dfa<dfa.decisionNumber>_min[<dfa.numberOfStates>] =
{<dfa.min; wrap="\n ", separator=",", null="0">};
const static unichar dfa<dfa.decisionNumber>_max[<dfa.numberOfStates>] =
{<dfa.max; wrap="\n ", separator=",", null="0">};
const static NSInteger dfa<dfa.decisionNumber>_accept[<dfa.numberOfStates>] =
{<dfa.accept; wrap="\n ", separator=",", null="-1">};
const static NSInteger dfa<dfa.decisionNumber>_special[<dfa.numberOfStates>] =
{<dfa.special; wrap="\n ", separator=",", null="-1">};
const static NSInteger dfa<dfa.decisionNumber>_transition[] = {};
<dfa.edgeTransitionClassMap.keys:{ table |
const static NSInteger dfa<dfa.decisionNumber>_transition<i0>[] = {<table; separator=", ", wrap="\n ", null="-1">\};
}; null="">
+ (id) newDFA<dfa.decisionNumber>WithRecognizer:(ANTLRBaseRecognizer *)aRecognizer
{
return [[[DFA<dfa.decisionNumber> alloc] initWithRecognizer:aRecognizer] retain];
}
- (id) initWithRecognizer:(ANTLRBaseRecognizer *) theRecognizer
{
self = [super initWithRecognizer:theRecognizer];
if ( self != nil ) {
decisionNumber = <dfa.decisionNumber>;
eot = dfa<dfa.decisionNumber>_eot;
eof = dfa<dfa.decisionNumber>_eof;
min = dfa<dfa.decisionNumber>_min;
max = dfa<dfa.decisionNumber>_max;
accept = dfa<dfa.decisionNumber>_accept;
special = dfa<dfa.decisionNumber>_special;
if (!(transition = calloc(<dfa.numberOfStates>, sizeof(void*)))) {
[self release];
return nil;
}
len = <dfa.numberOfStates>;
<dfa.transitionEdgeTables:{whichTable|transition[<i0>] = dfa<dfa.decisionNumber>_transition<whichTable>;}; separator="\n", null="">
}
return self;
}
<if(dfa.specialStateSTs)>
/* start dfa.specialStateSTs */
- (NSInteger) specialStateTransition:(NSInteger)s Stream:(id\<ANTLRIntStream\>)anInput
{
<if(LEXER)>
id\<ANTLRIntStream\> input = anInput;<\n>
<endif>
<if(PARSER)>
id\<ANTLRTokenStream\> input = (id\<ANTLRTokenStream\>)anInput;<\n>
<endif>
<if(TREE_PARSER)>
id\<ANTLRTreeNodeStream\> input = (id\<ANTLRTreeNodeStream\>)anInput;<\n>
<endif>
switch (s) {
<dfa.specialStateSTs:{state |
case <i0> : ;<! compressed special state numbers 0..n-1 !>
<state>}; separator="\n">
}
<if(backtracking)>
if ( [recognizer getBacktrackingLevel] > 0 ) { [recognizer setFailed:YES]; return -1; }<\n>
<endif>
ANTLRNoViableAltException *nvae = [ANTLRNoViableAltException newException:<dfa.decisionNumber> state:s stream:recognizer.input];
// nvae.c = s;
/* [self error:nvae]; */ <! for debugger - do later !>
@throw nvae;
}<\n>
/* end dfa.specialStateSTs */
<endif>
- (void) dealloc
{
free(transition);
[super dealloc];
}
- (NSString *) description
{
return @"<dfa.description>";
}
<@errorMethod()>
@end /* end DFA<dfa.decisionNumber> implementation */<\n>
#pragma mark Cyclic DFA implementation end DFA<dfa.decisionNumber>
<\n>
>>
/** A state in a cyclic DFA; it's a special state and part of a big switch on
* state.
*/
cyclicDFAState(decisionNumber, stateNumber, edges, needErrorClause, semPredState) ::= <<
/* cyclicDFAState */
NSInteger LA<decisionNumber>_<stateNumber> = [input LA:1];<\n>
<if(semPredState)> <! get next lookahead symbol to test edges, then rewind !>
NSInteger index<decisionNumber>_<stateNumber> = input.index;
[input rewind];<\n>
<endif>
s = -1;
<edges; separator="\nelse ">
<if(semPredState)> <! return input cursor to state before we rewound !>
[input seek:index<decisionNumber>_<stateNumber>];<\n>
<endif>
if ( s >= 0 )
return s;
break;
>>
/** Just like a fixed DFA edge, test the lookahead and indicate what
* state to jump to next if successful.
*/
cyclicDFAEdge(labelExpr, targetStateNumber, edgeNumber, predicates) ::= <<
/* cyclicDFAEdge */
if (<labelExpr><if(predicates)> && (<predicates>)<endif>) { s = <targetStateNumber>;}<\n>
>>
/** An edge pointing at end-of-token; essentially matches any char;
* always jump to the target.
*/
eotDFAEdge(targetStateNumber,edgeNumber, predicates) ::= <<
s = <targetStateNumber>;<\n> /* eotDFAEdge */
>>
// D F A E X P R E S S I O N S
andPredicates(left,right) ::= "(<left>&&<right>)"
orPredicates(operands) ::= "(<first(operands)><rest(operands):{o | ||<o>}>)"
notPredicate(pred) ::= "!(<evalPredicate(pred, \"\")>)"
evalPredicate(pred,description) ::= "(<pred>)"
/*
* evalSynPredicate(pred,description) ::= "<pred>()"
*
* synpreds are broken in cyclic DFA special states
* Damn! For now, work around with using the selectors directly, and by providing a trampoline evalSynPred method in
* ANTLRDFA
*/
/* evalSynPredicate(pred,description) ::= "[self evaluateSyntacticPredicate:<pred>Selector stream:input]" */
evalSynPredicate(pred,description) ::= "[self evaluateSyntacticPredicate:@selector(<pred>_fragment)]"
/* evalSynPredicate(pred,description) ::= "[recognizer <pred>]" */
lookaheadTest(atom,k,atomAsInt) ::= "LA<decisionNumber>_<stateNumber>==<atom>"
/** Sometimes a lookahead test cannot assume that LA(k) is in a temp variable
* somewhere. Must ask for the lookahead directly.
*/
isolatedLookaheadTest(atom,k,atomAsInt) ::= "[input LA:<k>] == <atom>"
lookaheadRangeTest(lower,upper,k,rangeNumber,lowerAsInt,upperAsInt) ::= <%
(LA<decisionNumber>_<stateNumber> >= <lower> && LA<decisionNumber>_<stateNumber> \<= <upper>)
%>
isolatedLookaheadRangeTest(lower,upper,k,rangeNumber,lowerAsInt,upperAsInt) ::= "(([input LA:<k>] >= <lower>) && ([input LA:<k>] \<= <upper>))"
setTest(ranges) ::= "<ranges; separator=\"||\">"
// A T T R I B U T E S
memVars(scope) ::= << <scope.attributes:{a|<a.type> <a.name>;<\n>}; separator="\n"> >>
properties(scope) ::= <<
<scope.attributes:{a|@property (assign, getter=get<a.name>, setter=set<a.name>:) <a.type> <a.name>;<\n>}; separator="\n">
>>
methodsDecl(scope) ::= <<
<scope.attributes:{a|- (<a.type>)get<a.name>;<\n>- (void)set<a.name>:(<a.type>)aVal;<\n>}; separator="\n">
>>
synthesize(scope) ::= << <scope.attributes:{a|@synthesize <a.name>;}; separator="\n"> >>
methods(scope) ::= <%
<scope.attributes:{a|
- (<a.type>)get<a.name> { return( <a.name> ); \}<\n>
- (void)set<a.name>:(<a.type>)aVal { <a.name> = aVal; \}<\n>}; separator="\n">
%>
globalAttributeScopeInterface(scope) ::= <%
/* globalAttributeScopeInterface */<\n>
@interface <scope.name>_Scope : ANTLRSymbolsScope {<\n>
<if(scope.attributes)>
<memVars(scope)>
<endif>
}<\n>
<if(scope.attributes)>
/* start of globalAttributeScopeInterface properties */<\n>
<properties(scope)>
/* end globalAttributeScopeInterface properties */<\n>
<endif>
+ (<scope.name>_Scope *)new<scope.name>_Scope;<\n>
- (id) init;<\n>
<if(scope.attributes)>
/* start of globalAttributeScopeInterface methodsDecl */<\n>
<methodsDecl(scope)>
/* End of globalAttributeScopeInterface methodsDecl */<\n>
<endif>
@end /* end of <scope.name>_Scope interface */<\n>
%>
globalAttributeScopeMemVar(scope) ::= <%
/* globalAttributeScopeMemVar */<\n>
ANTLRSymbolStack *<scope.name>_stack;<\n>
<scope.name>_Scope *<scope.name>_scope;<\n>
%>
globalAttributeScopeImplementation(scope) ::= <%
@implementation <scope.name>_Scope /* globalAttributeScopeImplementation */<\n>
<if(scope.attributes)>
/* start of synthesize -- OBJC-Line 1750 */<\n>
<synthesize(scope)><\n>
<endif>
<\n>
+ (<scope.name>_Scope *)new<scope.name>_Scope<\n>
{<\n>
return [[<scope.name>_Scope alloc] init];<\n>
}<\n>
<\n>
- (id) init<\n>
{<\n>
self = [super init];<\n>
return self;<\n>
}<\n>
<\n>
<if(scope.attributes)>
/* start of iterate get and set functions */<\n>
<methods(scope)><\n>
/* End of iterate get and set functions */<\n>
<endif>
@end /* end of <scope.name>_Scope implementation */<\n><\n>
%>
globalAttributeScopeInit(scope) ::= <<
/* globalAttributeScopeInit */<\n>
<scope.name>_scope = [<scope.name>_Scope new<scope.name>_Scope];<\n>
<scope.name>_stack = [ANTLRSymbolStack newANTLRSymbolStackWithLen:30];<\n>
>>
globalAttributeScopeDealloc(scope) ::= << [<scope.name>_stack release];<\n> >>
globalAttributeScope(scope) ::= << static <scope.name>_stack;<\n> >>
ruleAttributeScopeMemVar(scope) ::= <%
/* ObjC ruleAttributeScopeMemVar */<\n>
<if(scope.attributes)>
<scope.name>_Scope *<scope.name>_scope; /* ObjC ruleAttributeScopeMemVar */<\n>
<endif>
%>
ruleAttributeScopeInterface(scope) ::= <%
<if(scope.attributes)>
/* start of ruleAttributeScopeInterface */<\n>
@interface <scope.name>_Scope : ANTLRSymbolsScope {<\n>
<memVars(scope)><\n>
}<\n>
<\n>
/* start property declarations */<\n>
<properties(scope)><\n>
/* start method declarations */<\n>
+ (<scope.name>_Scope *)new<scope.name>_Scope;<\n>
- (id) init;<\n>
<methodsDecl(scope)><\n>
@end /* end of ruleAttributeScopeInterface */<\n><\n>
<endif>
%>
ruleAttributeScopeImplementation(scope) ::= <%
<if(scope.attributes)>
@implementation <scope.name>_Scope /* start of ruleAttributeScopeImplementation */<\n>
<synthesize(scope)><\n>
<\n>
+ (<scope.name>_Scope *)new<scope.name>_Scope<\n>
{<\n>
return [[<scope.name>_Scope alloc] init];<\n>
}<\n>
<\n>
- (id) init<\n>
{<\n>
self = [super init];<\n>
return self;<\n>
}<\n>
<\n>
/* start of <scope.name>_Scope get and set functions */<\n>
<methods(scope)><\n>
/* End of <scope.name>_Scope get and set functions */<\n>
@end /* end of ruleAttributeScopeImplementation */<\n><\n>
<endif>
%>
ruleAttributeScopeInit(scope) ::= <%
/* ruleAttributeScopeInit */<\n>
<scope.name>_scope = [<scope.name>_Scope new<scope.name>_Scope];<\n>
<scope.name>_stack = [ANTLRSymbolStack newANTLRSymbolStackWithLen:30];<\n>
%>
ruleAttributeScopeDealloc(scope) ::= <% [<scope.name>_Scope release];<\n> %>
ruleAttributeScope(scope) ::= <%
<if(scope.attributes)>
/* ruleAttributeScope */<\n>
static ANTLRSymbolStack *<scope.name>_stack;<\n>
<endif>
%>
ruleAttributeScopeDecl(scope) ::= <%
/* ruleAttributeScopeDecl */<\n>
<if(scope.attributes)>
<scope.name>_Scope *<scope.name>_scope;<\n>
<endif>
%>
returnStructName(r) ::= "<className()>_<r.name>_return"
returnType() ::= <%
<if(!ruleDescriptor.isSynPred)>
<if(ruleDescriptor.hasMultipleReturnValues)>
<ruleDescriptor:returnStructName()> *
<else>
<if(ruleDescriptor.hasSingleReturnValue)>
<ruleDescriptor.singleValueReturnType>
<else>
void
<endif>
<endif>
<else>
void
<endif>
%>
/** Generate the Objective-C type associated with a single or multiple return
* values.
*/
ruleLabelType(referencedRule) ::= <%
<if(referencedRule.hasMultipleReturnValues)>
<className()>_<referencedRule.name>_return *<else>
<if(referencedRule.hasSingleReturnValue)><referencedRule.singleValueReturnType><else>
void<endif>
<endif>
%>
delegateName(d) ::= << <if(d.label)><d.label><else>g<d.name><endif> >>
/** Using a type to init value map, try to init a type; if not in table
* must be an object, default value is "null".
*/
initValue(typeName) ::= <% <objcTypeInitMap.(typeName)> %>
/** Define a rule label including default value */
ruleLabelDef(label) ::= << <ruleLabelType(referencedRule=label.referencedRule)> <label.label.text> = <initValue(typeName=ruleLabelType(referencedRule=label.referencedRule))>;<\n> >>
/** Define a return struct for a rule if the code needs to access its
* start/stop tokens, tree stuff, attributes, ... Leave a hole for
* subgroups to stick in members.
*/
returnScopeInterface(scope) ::= <<
<if(ruleDescriptor.hasMultipleReturnValues)>
/* returnScopeInterface <ruleDescriptor:returnStructName()> */
@interface <ruleDescriptor:returnStructName()> : ANTLR<if(TREE_PARSER)>Tree<else>Parser<endif>RuleReturnScope { /* returnScopeInterface line 1838 */
<@memVars()> /* ObjC start of memVars() */<\n>
<if(scope.attributes)>
<memVars(scope)><\n>
<endif>
}
/* start property declarations */
<@properties()><\n>
<if(scope.attributes)>
<properties(scope)><\n>
<endif>
/* start of method declarations */<\n>
+ (<ruleDescriptor:returnStructName()> *)new<ruleDescriptor:returnStructName()>;
/* this is start of set and get methods */
<@methodsDecl()> /* methodsDecl */<\n>
<if(scope.attributes)>
/* start of iterated get and set functions */<\n>
<methodsDecl(scope)><\n>
<endif>
@end /* end of returnScopeInterface interface */<\n>
<endif>
>>
returnScopeImplementation(scope) ::= <%
<if(ruleDescriptor.hasMultipleReturnValues)>
@implementation <ruleDescriptor:returnStructName()> /* returnScopeImplementation */<\n>
<@synthesize()> /* start of synthesize -- OBJC-Line 1837 */<\n>
<if(scope.attributes)>
<synthesize(scope)><\n>
<endif>
+ (<ruleDescriptor:returnStructName()> *)new<ruleDescriptor:returnStructName()><\n>
{<\n>
return [[[<ruleDescriptor:returnStructName()> alloc] init] retain];<\n>
}<\n>
<\n>
- (id) init<\n>
{<\n>
self = [super init];<\n>
return self;<\n>
}<\n>
<\n>
<@methods()><\n>
<if(scope.attributes)>
/* start of iterate get and set functions */<\n>
<methods(scope)><\n>
/* End of iterate get and set functions */<\n>
<endif>
<actions.(actionScope).ruleReturnMethods>
<@ruleReturnMembers()><\n>
@end /* end of returnScope implementation */<\n><\n>
<endif>
%>
parameterScope(scope) ::= <<
<! <scope.attributes:{it | :(<it.type>)<it.name>}; separator=" "> !>
<first(scope.attributes):{ a | :(<a.type>)<a.name>}> <rest(scope.attributes):{ a | arg<i>:(<a.type>)<a.name> }; separator=" ">
>>
parameterAttributeRef(attr) ::= "<attr.name>"
parameterSetAttributeRef(attr,expr) ::= "<attr.name> = <expr>;"
/** Note that the scopeAttributeRef does not have access to the
* grammar name directly
*/
scopeAttributeRef(scope,attr,index,negIndex) ::= <%
<if(negIndex)>
([((<scope>_Scope *)[<scope>_stack objectAtIndex:[<scope>_stack size]-<negIndex>-1)]).<attr.name>
<else>
<if(index)>
((<scope>_Scope *)[<scope>_stack objectAtIndex:<index>]).<attr.name>
<else>
((<scope>_Scope *)[<scope>_stack peek]).<attr.name>
<endif>
<endif>
%>
scopeSetAttributeRef(scope,attr,expr,index,negIndex) ::= <%
/* scopeSetAttributeRef */
<if(negIndex)>
((<scope>_Scope *)[<scope>_stack objectAtIndex:([<scope>_stack size]-<negIndex>-1)]).<attr.name> = <expr>;
<else>
<if(index)>
((<scope>_Scope *)[<scope>_stack objectAtIndex:<index>]).<attr.name> = <expr>;
<else>
((<scope>_Scope *)[<scope>_stack peek]).<attr.name> = <expr>;
<endif>
<endif>
%>
scopeAttributeRefStack() ::= <<
/* scopeAttributeRefStack */
<if(negIndex)>
((<scope>_Scope *)[<scope>_stack objectAtIndex:[<scope>_stack count]-<negIndex>-1]).<attr.name> = <expr>;
<else>
<if(index)>
((<scope>_Scope *)[<scope>_stack objectAtIndex:<index>]).<attr.name> = <expr>;
<else>
((<scope>_Scope *)[<scope>_stack peek]).<attr.name> = <expr>;
<endif>
<endif>
>>
/** $x is either global scope or x is rule with dynamic scope; refers
* to stack itself not top of stack. This is useful for predicates
* like {$function.size()>0 && $function::name.equals("foo")}?
*/
isolatedDynamicScopeRef(scope) ::= "<scope>_stack"
/** reference an attribute of rule; might only have single return value */
ruleLabelRef(referencedRule,scope,attr) ::= <<
<if(referencedRule.hasMultipleReturnValues)>
(<scope>!=nil?<scope>.<attr.name>:<initValue(attr.type)>)
<else>
<scope>
<endif>
>>
returnAttributeRef(ruleDescriptor,attr) ::= <%
<if(ruleDescriptor.hasMultipleReturnValues)>
retval.<attr.name> /* added to returnAttributeRef */<\n>
<else>
<attr.name><\n>
<endif>
%>
returnSetAttributeRef(ruleDescriptor,attr,expr) ::= <%
<if(ruleDescriptor.hasMultipleReturnValues)>
retval.<attr.name> =<expr>; /* added to returnSetAttributeRef */<\n>
<else>
<attr.name> = <expr>;<\n>
<endif>
%>
/** How to translate $tokenLabel */
tokenLabelRef(label) ::= "<label>"
/** ids+=ID {$ids} or e+=expr {$e} */
listLabelRef(label) ::= "list_<label>"
/* not sure the next are the right approach; and they are evaluated early; */
/* they cannot see TREE_PARSER or PARSER attributes for example. :( */
tokenLabelPropertyRef_text(scope,attr) ::= "(<scope>!=nil?<scope>.text:nil)"
tokenLabelPropertyRef_type(scope,attr) ::= "(<scope>!=nil?<scope>.type:0)"
tokenLabelPropertyRef_line(scope,attr) ::= "(<scope>!=nil?<scope>.line:0)"
tokenLabelPropertyRef_pos(scope,attr) ::= "(<scope>!=nil?<scope>.charPositionInLine:0)"
tokenLabelPropertyRef_channel(scope,attr) ::= "(<scope>!=nil?<scope>.channel:0)"
tokenLabelPropertyRef_index(scope,attr) ::= "(<scope>!=nil?[<scope> getTokenIndex]:0)"
tokenLabelPropertyRef_tree(scope,attr) ::= "<scope>_tree"
tokenLabelPropertyRef_int(scope,attr) ::= "(<scope>!=nil?[<scope>.text integerValue]:0)"
ruleLabelPropertyRef_start(scope,attr) ::= "(<scope>!=nil?((<labelType> *)<scope>.start):nil)"
ruleLabelPropertyRef_stop(scope,attr) ::= "(<scope>!=nil?((<labelType> *)<scope>.stopToken):nil)"
ruleLabelPropertyRef_tree(scope,attr) ::= "(<scope>!=nil?((<ASTLabelType> *)<scope>.tree):nil)"
ruleLabelPropertyRef_text(scope,attr) ::= <%
<if(TREE_PARSER)>
(<scope>!=nil?[[input getTokenStream] toStringFromStart:[[input getTreeAdaptor] getTokenStartIndex:[<scope> getStart]]
ToEnd:[[input getTreeAdaptor] getTokenStopIndex:[<scope> getStart]]]:0)
<else>
(<scope>!=nil?([input toStringFromStart:[<scope> getStart] ToEnd:[<scope> getStop]]:0)
<endif>
%>
ruleLabelPropertyRef_st(scope,attr) ::= "(<scope>!=nil?[<scope> st]:nil)"
/** Isolated $RULE ref ok in lexer as it's a Token */
lexerRuleLabel(label) ::= "<label>"
lexerRuleLabelPropertyRef_type(scope,attr) ::= "(<scope>!=nil?<scope>.type:0)"
lexerRuleLabelPropertyRef_line(scope,attr) ::= "(<scope>!=nil?<scope>.line:0)"
lexerRuleLabelPropertyRef_pos(scope,attr) ::= "(<scope>!=nil?<scope>.charPositionInLine:-1)"
lexerRuleLabelPropertyRef_channel(scope,attr) ::= "(<scope>!=nil?<scope>.channel:0)"
lexerRuleLabelPropertyRef_index(scope,attr) ::= "(<scope>!=nil?[<scope> getTokenIndex]:0)"
lexerRuleLabelPropertyRef_text(scope,attr) ::= "(<scope>!=nil?<scope>.text:nil)"
lexerRuleLabelPropertyRef_int(scope,attr) ::="(<scope>!=nil?[<scope>.text integerValue]:0)"
// Somebody may ref $template or $tree or $stop within a rule:
rulePropertyRef_start(scope,attr) ::= "((<labelType> *)retval.start)"
rulePropertyRef_stop(scope,attr) ::= "((<labelType> *)retval.stopToken)"
rulePropertyRef_tree(scope,attr) ::= "((<ASTLabelType> *)retval.tree)"
rulePropertyRef_text(scope,attr) ::= <<
<if(TREE_PARSER)>
[[input getTokenStream] toStringFromStart:[[input getTreeAdaptor] getTokenStartIndex:retval.start.token.startIndex]
ToEnd:[[input getTreeAdaptor] getTokenStopIndex:retval.start.token.stopIndex]]
<else>
[input toStringFromToken:retval.start ToToken:[input LT:-1]]
<endif>
>>
rulePropertyRef_st(scope,attr) ::= "retval.st"
/* hideous: find a way to cut down on the number of templates to support read/write access */
/* TODO: also, which ones are valid to write to? ask Ter */
lexerRuleSetPropertyRef_text(scope,attr,expr) ::= "state.text = <expr>;"
lexerRuleSetPropertyRef_type(scope,attr,expr) ::= "_type"
lexerRuleSetPropertyRef_line(scope,attr,expr) ::= "state.tokenStartLine"
lexerRuleSetPropertyRef_pos(scope,attr,expr) ::= "state.tokenStartCharPositionInLine"
lexerRuleSetPropertyRef_index(scope,attr,expr) ::= "-1" /* undefined token index in lexer */
lexerRuleSetPropertyRef_channel(scope,attr,expr) ::= "state.channel=<expr>;"
lexerRuleSetPropertyRef_start(scope,attr,expr) ::= "state.tokenStartCharIndex"
lexerRuleSetPropertyRef_stop(scope,attr,expr) ::= "(input.index-1)"
lexerRulePropertyRef_text(scope,attr) ::= "self.text"
lexerRulePropertyRef_type(scope,attr) ::= "state.type"
lexerRulePropertyRef_line(scope,attr) ::= "state.tokenStartLine"
lexerRulePropertyRef_pos(scope,attr) ::= "state.tokenStartCharPositionInLine"
lexerRulePropertyRef_index(scope,attr) ::= "-1" // undefined token index in lexer
lexerRulePropertyRef_channel(scope,attr) ::= "_channel"
lexerRulePropertyRef_start(scope,attr) ::= "state.tokenStartCharIndex"
lexerRulePropertyRef_stop(scope,attr) ::= "(input.index-1)"
lexerRulePropertyRef_int(scope,attr) ::= "[<scope>.text integerValue]"
// setting $st and $tree is allowed in local rule. everything else
// is flagged as error
ruleSetPropertyRef_tree(scope,attr,expr) ::= "retval.start =<expr>;"
ruleSetPropertyRef_st(scope,attr,expr) ::= "retval.st =<expr>;" /* "<\n>#error StringTemplates are unsupported<\n>" */
/** How to execute an action */
execAction(action) ::= <<
<if(backtracking)>
if ( <actions.(actionScope).synpredgate> ) {
<action>
}
<else>
<action>
<endif>
>>
/** How to always execute an action even when backtracking */
execForcedAction(action) ::= "<action>"
// M I S C (properties, etc...)
bitset(name, words64) ::= <<
static ANTLRBitSet *<name>;
static const unsigned long long <name>_data[] = { <words64:{it | <it>LL};separator=", ">};<\n>
>>
bitsetInit(name, words64) ::= <<
<name> = [[ANTLRBitSet newANTLRBitSetWithBits:(const unsigned long long *)<name>_data Count:(NSUInteger)<length(words64)>] retain];<\n>
>>
codeFileExtension() ::= ".m"
true_value() ::= "YES"
false_value() ::= "NO"