blob: 8e5d60362f59b0565ef6677d3e3776b59b06b58a [file] [log] [blame]
/*
* [The "BSD license"]
* Copyright (c) 2007-2008 Johannes Luber
* Copyright (c) 2005-2007 Kunle Odutola
* Copyright (c) 2011 Sam Harwell
* Copyright (c) 2011 Terence Parr
* 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.
*/
csharpVisibilityMap ::= [
"private":"private",
"protected":"protected",
"public":"public",
"fragment":"private",
default:"private"
]
/** 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) ::=
<<
//------------------------------------------------------------------------------
// \<auto-generated>
// This code was generated by a tool.
// ANTLR Version: <ANTLRVersion>
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// \</auto-generated>
//------------------------------------------------------------------------------
// $ANTLR <ANTLRVersion> <fileName> <generatedTimestamp>
<if(trace)>
#define ANTLR_TRACE
<endif>
<@debugPreprocessor()>
// The variable 'variable' is assigned but its value is never used.
#pragma warning disable 168, 219
// Unreachable code detected.
#pragma warning disable 162
// Missing XML comment for publicly visible type or member 'Type_or_Member'
#pragma warning disable 1591
<actions.(actionScope).header>
<@imports>
using System.Collections.Generic;
using Antlr.Runtime;
using Antlr.Runtime.Misc;
<if(TREE_PARSER)>
using Antlr.Runtime.Tree;
using RewriteRuleITokenStream = Antlr.Runtime.Tree.RewriteRuleTokenStream;
<endif>
using ConditionalAttribute = System.Diagnostics.ConditionalAttribute;
<@end>
<if(actions.(actionScope).namespace)>
namespace <actions.(actionScope).namespace>
{
<endif>
<docComment>
<recognizer>
<if(actions.(actionScope).namespace)>
} // namespace <actions.(actionScope).namespace>
<endif>
>>
lexerInputStreamType() ::= <<
<actions.(actionScope).inputStreamType; null="ICharStream">
>>
lexer(grammar, name, tokens, scopes, rules, numRules, filterMode, labelType="CommonToken",
superClass={<if(actions.(actionScope).superClass)><actions.(actionScope).superClass><else>Antlr.Runtime.Lexer<endif>}) ::= <<
[System.CodeDom.Compiler.GeneratedCode("ANTLR", "<ANTLRVersion>")]
[System.CLSCompliant(false)]
<parserModifier(grammar=grammar, actions=actions)> partial class <grammar.recognizerName> : <@superClassName><superClass><@end>
{
<tokens:{it|public const int <it.name; format="id">=<it.type>;}; separator="\n">
<scopes:{it|<if(it.isDynamicGlobalScope)><globalAttributeScope(scope=it)><endif>}>
<actions.lexer.members>
// delegates
<grammar.delegates:
{g|private <g.recognizerName> <g:delegateName()>;}; separator="\n">
// delegators
<grammar.delegators:
{g|private <g.recognizerName> <g:delegateName()>;}; separator="\n">
<last(grammar.delegators):{g|private <g.recognizerName> gParent;}>
<actions.(actionScope).ctorModifier; null="public"> <grammar.recognizerName>()<! needed by subclasses !>
{
OnCreated();
}
<actions.(actionScope).ctorModifier; null="public"> <grammar.recognizerName>(<lexerInputStreamType()> input<grammar.delegators:{g|, <g.recognizerName> <g:delegateName()>}> )
: this(input, new RecognizerSharedState()<grammar.delegators:{g|, <g:delegateName()>}>)
{
}
<actions.(actionScope).ctorModifier; null="public"> <grammar.recognizerName>(<lexerInputStreamType()> input, RecognizerSharedState state<grammar.delegators:{g|, <g.recognizerName> <g:delegateName()>}>)
: base(input, state)
{
<if(memoize)>
<if(grammar.grammarIsRoot)>
state.ruleMemo = new System.Collections.Generic.Dictionary\<int, int>[<numRules>+1];<\n><! index from 1..n !>
<endif>
<endif>
<grammar.directDelegates:
{g|<g:delegateName()> = new <g.recognizerName>(input, this.state<trunc(g.delegators):{p|, <p:delegateName()>}>, this);}; separator="\n">
<grammar.delegators:
{g|this.<g:delegateName()> = <g:delegateName()>;}; separator="\n">
<last(grammar.delegators):{g|gParent = <g:delegateName()>;}>
OnCreated();
}
public override string GrammarFileName { get { return "<fileName>"; } }
private static readonly bool[] decisionCanBacktrack = new bool[0];
<if(grammar.hasDelegates)>
public override <lexerInputStreamType()> CharStream
{
get
{
return base.CharStream;
}
set
{
base.CharStream = value;
<grammar.directDelegates:
{g|<g:delegateName()> = new <g.recognizerName>(input, state<trunc(g.delegators):{p|, <p:delegateName()>}>, this);}; separator="\n">
<grammar.delegators:
{g|this.<g:delegateName()> = <g:delegateName()>;}; separator="\n">
<last(grammar.delegators):{g|gParent = <g:delegateName()>;}>
}
}
<endif>
<if(filterMode)>
<filteringNextToken()>
<endif>
[Conditional("ANTLR_TRACE")]
protected virtual void OnCreated() {}
[Conditional("ANTLR_TRACE")]
protected virtual void EnterRule(string ruleName, int ruleIndex) {}
[Conditional("ANTLR_TRACE")]
protected virtual void LeaveRule(string ruleName, int ruleIndex) {}
<rules; separator="\n">
<insertLexerSynpreds(synpreds)>
#region DFA
<cyclicDFAs:{dfa | DFA<dfa.decisionNumber> dfa<dfa.decisionNumber>;}; separator="\n">
protected override void InitDFAs()
{
base.InitDFAs();
<cyclicDFAs:{dfa | dfa<dfa.decisionNumber> = new DFA<dfa.decisionNumber>(this<if(dfa.specialStateSTs)>, SpecialStateTransition<dfa.decisionNumber><endif>);}; separator="\n">
}
<cyclicDFAs:cyclicDFA()> <! dump tables for all DFA !>
#endregion
}
>>
/** 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() ::= <<
public override IToken NextToken()
{
while (true)
{
if (input.LA(1) == CharStreamConstants.EndOfFile)
{
IToken eof = new CommonToken((ICharStream)input, CharStreamConstants.EndOfFile, TokenChannels.Default, input.Index, input.Index);
eof.Line = Line;
eof.CharPositionInLine = CharPositionInLine;
return eof;
}
state.token = null;
state.channel = TokenChannels.Default;
state.tokenStartCharIndex = input.Index;
state.tokenStartCharPositionInLine = input.CharPositionInLine;
state.tokenStartLine = input.Line;
state.text = null;
try
{
int m = input.Mark();
state.backtracking=1;<! means we won't throw slow exception !>
state.failed=false;
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
{
Emit();
return state.token;
}
}
catch (RecognitionException re)
{
// shouldn't happen in backtracking mode, but...
ReportError(re);
Recover(re);
}
}
}
public override void Memoize(IIntStream input, int ruleIndex, int ruleStartIndex)
{
if (state.backtracking > 1)
base.Memoize(input, ruleIndex, ruleStartIndex);
}
public override bool AlreadyParsedRule(IIntStream input, int ruleIndex)
{
if (state.backtracking > 1)
return base.AlreadyParsedRule(input, ruleIndex);
return false;
}
>>
actionGate() ::= "state.backtracking == 0"
filteringActionGate() ::= "state.backtracking == 1"
/** How to generate a parser */
genericParser(grammar, name, scopes, tokens, tokenNames, rules, numRules,
bitsets, inputStreamType, superClass,
labelType, members, rewriteElementType,
filterMode, ASTLabelType="object") ::= <<
[System.CodeDom.Compiler.GeneratedCode("ANTLR", "<ANTLRVersion>")]
[System.CLSCompliant(false)]
<parserModifier(grammar=grammar, actions=actions)> partial class <grammar.recognizerName> : <@superClassName><superClass><@end>
{
<if(grammar.grammarIsRoot)>
internal static readonly string[] tokenNames = new string[] {
"\<invalid>", "\<EOR>", "\<DOWN>", "\<UP>", <tokenNames; separator=", ">
};
<endif>
<tokens:{it|public const int <it.name; format="id">=<it.type>;}; separator="\n">
<if(grammar.delegates)>
// delegates
<grammar.delegates:
{g|private <g.recognizerName> <g:delegateName()>;}; separator="\n">
<endif>
<if(grammar.delegators)>
// delegators
<grammar.delegators:
{g|private <g.recognizerName> <g:delegateName()>;}; separator="\n">
<last(grammar.delegators):{g|private <g.recognizerName> gParent;}>
<endif>
<scopes:{it|<if(it.isDynamicGlobalScope)><globalAttributeScope(scope=it)><endif>}>
<@members()>
public override string[] TokenNames { get { return <grammar.composite.rootGrammar.recognizerName>.tokenNames; } }
public override string GrammarFileName { get { return "<fileName>"; } }
<members>
[Conditional("ANTLR_TRACE")]
protected virtual void OnCreated() {}
[Conditional("ANTLR_TRACE")]
protected virtual void EnterRule(string ruleName, int ruleIndex) {}
[Conditional("ANTLR_TRACE")]
protected virtual void LeaveRule(string ruleName, int ruleIndex) {}
#region Rules
<rules; separator="\n">
#endregion Rules
<if(grammar.delegatedRules)>
<! generate rule/method definitions for imported rules so they
appear to be defined in this recognizer. !>
#region Delegated rules
<grammar.delegatedRules:{ruleDescriptor|
<ruleModifier(grammar=grammar,ruleDescriptor=ruleDescriptor)> <returnType(ruleDescriptor)> <ruleDescriptor.name; format="id">(<ruleDescriptor.parameterScope:parameterScope()>) <!throws RecognitionException !>{ <if(ruleDescriptor.hasReturnValue)>return <endif><ruleDescriptor.grammar:delegateName()>.<ruleDescriptor.name; format="id">(<ruleDescriptor.parameterScope.attributes:{a|<a.name; format="id">}; separator=", ">); \}}; separator="\n">
#endregion Delegated rules
<endif>
<insertSynpreds(synpreds)>
<if(cyclicDFAs)>
#region DFA
<cyclicDFAs:{dfa | private DFA<dfa.decisionNumber> dfa<dfa.decisionNumber>;}; separator="\n">
protected override void InitDFAs()
{
base.InitDFAs();
<cyclicDFAs:{dfa | dfa<dfa.decisionNumber> = new DFA<dfa.decisionNumber>( this<if(dfa.specialStateSTs)>, SpecialStateTransition<dfa.decisionNumber><endif> );}; separator="\n">
}
<cyclicDFAs:cyclicDFA()><! dump tables for all DFA !>
#endregion DFA
<endif>
<if(bitsets)>
#region Follow sets
private static class Follow
{
<bitsets:{it|<bitset(name={_<it.name>_in_<it.inName><it.tokenIndex>}, words64=it.bits)>}; separator="\n">
}
#endregion Follow sets
<endif>
}
>>
@genericParser.members() ::= <<
#if ANTLR_DEBUG
private static readonly bool[] decisionCanBacktrack =
new bool[]
{
false, // invalid decision
<grammar.decisions:{d | <d.dfa.hasSynPred>}; wrap="\n", separator=", ">
};
#else
private static readonly bool[] decisionCanBacktrack = new bool[0];
#endif
<! WARNING. bug in ST: this is cut-n-paste into Dbg.stg !>
<actions.(actionScope).ctorModifier; null="public"> <grammar.recognizerName>(<inputStreamType> input<grammar.delegators:{g|, <g.recognizerName> <g:delegateName()>}>)
: this(input, new RecognizerSharedState()<grammar.delegators:{g|, <g:delegateName()>}>)
{
}
<actions.(actionScope).ctorModifier; null="public"> <grammar.recognizerName>(<inputStreamType> input, RecognizerSharedState state<grammar.delegators:{g|, <g.recognizerName> <g:delegateName()>}>)
: base(input, state)
{
<parserCtorBody()>
<if(grammar.directDelegates)>
<grammar.directDelegates:
{g|<g:delegateName()> = new <g.recognizerName>(input, state<trunc(g.delegators):{p|, <p:delegateName()>}>, this);}; separator="\n">
<endif>
<if(grammar.indirectDelegates)>
<grammar.indirectDelegates:{g | <g:delegateName()> = <g.delegator:delegateName()>.<g:delegateName()>;}; separator="\n">
<endif>
<if(grammar.delegators)>
<last(grammar.delegators):{g|gParent = <g:delegateName()>;}>
<endif>
OnCreated();
}
>>
// imported grammars are 'public' (can't be internal because their return scope classes must be accessible)
parserModifier(grammar, actions) ::= <<
<if(grammar.grammarIsRoot)><actions.(actionScope).modifier; null="public"><else>public<endif>
>>
parserCtorBody() ::= <<
<if(memoize)>
<if(grammar.grammarIsRoot)>
this.state.ruleMemo = new System.Collections.Generic.Dictionary\<int, int>[<length(grammar.allImportedRules)>+1];<\n><! index from 1..n !>
<endif>
<endif>
<grammar.delegators:
{g|this.<g:delegateName()> = <g:delegateName()>;}; separator="\n">
>>
parser(grammar, name, scopes, tokens, tokenNames, rules, numRules, bitsets,
ASTLabelType="object", superClass={<if(actions.(actionScope).superClass)><actions.(actionScope).superClass><else>Antlr.Runtime.Parser<endif>}, labelType="IToken",
members={<actions.parser.members>}) ::= <<
<genericParser(inputStreamType="ITokenStream", rewriteElementType="IToken", ...)>
>>
/** 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="object",
superClass={<if(actions.(actionScope).superClass)><actions.(actionScope).superClass><else>Antlr.Runtime.Tree.<if(filterMode)><if(buildAST)>TreeRewriter<else>TreeFilter<endif><else>TreeParser<endif><endif>},
members={<actions.treeparser.members>}) ::= <<
<genericParser(inputStreamType="ITreeNodeStream", rewriteElementType="Node", ...)>
>>
/** 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) ::=
<<
[Conditional("ANTLR_TRACE")]
protected virtual void EnterRule_<ruleName>_fragment() {}
[Conditional("ANTLR_TRACE")]
protected virtual void LeaveRule_<ruleName>_fragment() {}
// $ANTLR start <ruleName>
public <!final !>void <ruleName>_fragment(<ruleDescriptor.parameterScope:parameterScope()>)
{
<ruleLabelDefs()>
EnterRule_<ruleName>_fragment();
EnterRule("<ruleName>_fragment", <ruleDescriptor.index>);
TraceIn("<ruleName>_fragment", <ruleDescriptor.index>);
try
{
<block>
}
finally
{
TraceOut("<ruleName>_fragment", <ruleDescriptor.index>);
LeaveRule("<ruleName>_fragment", <ruleDescriptor.index>);
LeaveRule_<ruleName>_fragment();
}
}
// $ANTLR end <ruleName>
>>
insertLexerSynpreds(synpreds) ::= <<
<insertSynpreds(synpreds)>
>>
insertSynpreds(synpreds) ::= <<
<if(synpreds)>
#region Synpreds
private bool EvaluatePredicate(System.Action fragment)
{
bool success = false;
state.backtracking++;
<@start()>
try { DebugBeginBacktrack(state.backtracking);
int start = input.Mark();
try
{
fragment();
}
catch ( RecognitionException re )
{
System.Console.Error.WriteLine("impossible: "+re);
}
success = !state.failed;
input.Rewind(start);
} finally { DebugEndBacktrack(state.backtracking, success); }
<@stop()>
state.backtracking--;
state.failed=false;
return success;
}
#endregion Synpreds
<endif>
>>
ruleMemoization(name) ::= <<
<if(memoize)>
if (state.backtracking > 0 && AlreadyParsedRule(input, <ruleDescriptor.index>)) { <returnFromRule()> }
<endif>
>>
/** How to test for failure and return from rule */
checkRuleBacktrackFailure() ::= <<
<if(backtracking)>if (state.failed) <returnFromRule()><endif>
>>
/** This rule has failed, exit indicating failure during backtrack */
ruleBacktrackFailure() ::= <<
<if(backtracking)>if (state.backtracking>0) {state.failed=true; <returnFromRule()>}<endif>
>>
/** How to generate code for a rule. This includes any return type
* data aggregates required for multiple return values.
*/
rule(ruleName,ruleDescriptor,block,emptyRule,description,exceptions,finally,memoize) ::= <<
<ruleAttributeScope(scope=ruleDescriptor.ruleScope)>
<returnScope(ruleDescriptor.returnScope)>
[Conditional("ANTLR_TRACE")]
protected virtual void EnterRule_<ruleName>() {}
[Conditional("ANTLR_TRACE")]
protected virtual void LeaveRule_<ruleName>() {}
// $ANTLR start "<ruleName>"
// <fileName>:<description>
[GrammarRule("<ruleName>")]
<ruleModifier(grammar=grammar,ruleDescriptor=ruleDescriptor)> <returnType(ruleDescriptor)> <ruleName; format="id">(<ruleDescriptor.parameterScope:parameterScope()>)
{
EnterRule_<ruleName>();
EnterRule("<ruleName>", <ruleDescriptor.index>);
TraceIn("<ruleName>", <ruleDescriptor.index>);
<ruleScopeSetUp()>
<ruleDeclarations()>
<ruleLabelDefs()>
<ruleDescriptor.actions.init>
try { DebugEnterRule(GrammarFileName, "<ruleName>");
DebugLocation(<ruleDescriptor.tree.line>, <ruleDescriptor.EORNode.charPositionInLine>);
<@preamble()>
try
{
<ruleMemoization(name=ruleName)>
<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 (RecognitionException re)
{
ReportError(re);
Recover(input,re);
<@setErrorReturnValue()>
}
<endif>
<endif>
<endif>
finally
{
TraceOut("<ruleName>", <ruleDescriptor.index>);
LeaveRule("<ruleName>", <ruleDescriptor.index>);
LeaveRule_<ruleName>();
<memoize()>
<ruleScopeCleanUp()>
<finally>
}
DebugLocation(<ruleDescriptor.EORNode.line>, <ruleDescriptor.EORNode.charPositionInLine>);
} finally { DebugExitRule(GrammarFileName, "<ruleName>"); }
<@postamble()>
<returnFromRule()><\n>
}
// $ANTLR end "<ruleName>"
>>
// imported grammars need to have internal rules
ruleModifier(grammar,ruleDescriptor) ::= <<
<if(grammar.grammarIsRoot)><csharpVisibilityMap.(ruleDescriptor.modifier); null="private"><else>internal<endif>
>>
// imported grammars need to have public return scopes
returnScopeModifier(grammar,ruleDescriptor) ::= <<
<if(grammar.grammarIsRoot)><csharpVisibilityMap.(ruleDescriptor.modifier); null="private"><else>public<endif>
>>
catch(decl,action) ::= <<
catch (<e.decl>)
{
<e.action>
}
>>
ruleDeclarations() ::= <<
<if(ruleDescriptor.hasMultipleReturnValues)>
<returnType(ruleDescriptor)> retval = new <returnType(ruleDescriptor)>();
retval.Start = (<labelType>)input.LT(1);
<else>
<ruleDescriptor.returnScope.attributes:{ a |
<a.type> <a.name; format="id"> = <if(a.initValue)><a.initValue><else><initValue(a.type)><endif>;
}>
<endif>
<if(memoize)>
int <ruleDescriptor.name>_StartIndex = input.Index;
<endif>
>>
ruleScopeSetUp() ::= <<
<ruleDescriptor.useScopes:{it|<it>_stack.Push(new <it>_scope());<it>_scopeInit(<it>_stack.Peek());}; separator="\n">
<ruleDescriptor.ruleScope:{it|<it.name>_stack.Push(new <it.name>_scope());<it.name>_scopeInit(<it.name>_stack.Peek());}; separator="\n">
>>
ruleScopeCleanUp() ::= <<
<ruleDescriptor.useScopes:{it|<it>_scopeAfter(<it>_stack.Peek());<it>_stack.Pop();}; separator="\n">
<ruleDescriptor.ruleScope:{it|<it.name>_scopeAfter(<it.name>_stack.Peek());<it.name>_stack.Pop();}; separator="\n">
>>
ruleLabelDefs() ::= <<
<[ruleDescriptor.tokenLabels,ruleDescriptor.tokenListLabels,ruleDescriptor.wildcardTreeLabels,ruleDescriptor.wildcardTreeListLabels]
:{it|<labelType> <it.label.text> = default(<labelType>);}; separator="\n"
>
<ruleDescriptor.tokenListLabels
:{it|List\<<labelType>\> list_<it.label.text> = null;}; separator="\n"
>
<[ruleDescriptor.ruleListLabels,ruleDescriptor.wildcardTreeListLabels]
:{it|List\<<ASTLabelType>\> list_<it.label.text> = null;}; separator="\n"
>
<ruleDescriptor.ruleLabels:ruleLabelDef(); separator="\n">
<ruleDescriptor.ruleListLabels:ruleLabelDef(); separator="\n">
>>
lexerRuleLabelDefs() ::= <<
<[ruleDescriptor.tokenLabels,
ruleDescriptor.tokenListLabels,
ruleDescriptor.ruleLabels]
:{it|<labelType> <it.label.text> = default(<labelType>);}; separator="\n"
>
<[ruleDescriptor.charListLabels,
ruleDescriptor.charLabels]
:{it|int <it.label.text> = 0;}; separator="\n"
>
<[ruleDescriptor.tokenListLabels,
ruleDescriptor.ruleListLabels]
:{it|List\<<labelType>\> list_<it.label.text> = null;}; separator="\n"
>
<ruleDescriptor.charListLabels:{it|List\<int\> list_<it.label.text> = null;}; separator="\n"
>
>>
returnFromRule() ::= <%
return
<if(!ruleDescriptor.isSynPred)>
<if(ruleDescriptor.hasReturnValue)>
<if(ruleDescriptor.hasSingleReturnValue)>
<! This comment is a hack to make sure the following
single space appears in the output. !> <ruleDescriptor.singleValueReturnName>
<else>
<!!> retval
<endif>
<endif>
<endif>
;
%>
ruleCleanUp() ::= <<
<if(ruleDescriptor.hasMultipleReturnValues)>
<if(!TREE_PARSER)>
retval.Stop = (<labelType>)input.LT(-1);
<endif>
<endif>
>>
memoize() ::= <<
<if(memoize)>
<if(backtracking)>
if (state.backtracking > 0) { Memoize(input, <ruleDescriptor.index>, <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) ::= <<
[Conditional("ANTLR_TRACE")]
protected virtual void EnterRule_<ruleName>() {}
[Conditional("ANTLR_TRACE")]
protected virtual void LeaveRule_<ruleName>() {}
// $ANTLR start "<ruleName>"
[GrammarRule("<ruleName>")]
<ruleModifier(grammar=grammar,ruleDescriptor=ruleDescriptor)> void m<ruleName>(<ruleDescriptor.parameterScope:parameterScope()>)
{
EnterRule_<ruleName>();
EnterRule("<ruleName>", <ruleDescriptor.index>);
TraceIn("<ruleName>", <ruleDescriptor.index>);
<ruleScopeSetUp()>
<ruleDeclarations()>
try
{
<if(nakedBlock)>
<ruleMemoization(name=ruleName)>
<lexerRuleLabelDefs()>
<ruleDescriptor.actions.init>
<block>
<else>
int _type = <ruleName>;
int _channel = DefaultTokenChannel;
<ruleMemoization(name=ruleName)>
<lexerRuleLabelDefs()>
<ruleDescriptor.actions.init>
<block>
<ruleCleanUp()>
state.type = _type;
state.channel = _channel;
<(ruleDescriptor.actions.after):execAction()>
<endif>
}
finally
{
TraceOut("<ruleName>", <ruleDescriptor.index>);
LeaveRule("<ruleName>", <ruleDescriptor.index>);
LeaveRule_<ruleName>();
<ruleScopeCleanUp()>
<memoize()>
}
}
// $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) ::= <<
public override 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>
int alt<decisionNumber>=<maxAlt>;
<decls>
<@predecision()>
try { DebugEnterSubRule(<decisionNumber>);
try { DebugEnterDecision(<decisionNumber>, decisionCanBacktrack[<decisionNumber>]);
<decision>
} finally { DebugExitDecision(<decisionNumber>); }
<@postdecision()>
<@prebranch()>
switch (alt<decisionNumber>)
{
<alts:{a|<altSwitchCase(i,a)>}>
}
} finally { DebugExitSubRule(<decisionNumber>); }
<@postbranch()>
>>
/** A rule block with multiple alternatives */
ruleBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
// <fileName>:<description>
int alt<decisionNumber>=<maxAlt>;
<decls>
<@predecision()>
try { DebugEnterDecision(<decisionNumber>, decisionCanBacktrack[<decisionNumber>]);
<decision>
} finally { DebugExitDecision(<decisionNumber>); }
<@postdecision()>
switch (alt<decisionNumber>)
{
<alts:{a|<altSwitchCase(i,a)>}>
}
>>
ruleBlockSingleAlt(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,description) ::= <<
// <fileName>:<description>
<decls>
<@prealt()>
DebugEnterAlt(1);
<alts>
<@postalt()>
>>
/** A special case of a (...) subrule with a single alternative */
blockSingleAlt(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,description) ::= <<
// <fileName>:<description>
<decls>
<@prealt()>
DebugEnterAlt(1);
<alts>
<@postalt()>
>>
/** A (..)+ block with 1 or more alternatives */
positiveClosureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
// <fileName>:<description>
int cnt<decisionNumber>=0;
<decls>
<@preloop()>
try { DebugEnterSubRule(<decisionNumber>);
while (true)
{
int alt<decisionNumber>=<maxAlt>;
<@predecision()>
try { DebugEnterDecision(<decisionNumber>, decisionCanBacktrack[<decisionNumber>]);
<decision>
} finally { DebugExitDecision(<decisionNumber>); }
<@postdecision()>
switch (alt<decisionNumber>)
{
<alts:{a|<altSwitchCase(i,a)>}>
default:
if (cnt<decisionNumber> >= 1)
goto loop<decisionNumber>;
<ruleBacktrackFailure()>
EarlyExitException eee<decisionNumber> = new EarlyExitException( <decisionNumber>, input );
DebugRecognitionException(eee<decisionNumber>);
<@earlyExitException()>
throw eee<decisionNumber>;
}
cnt<decisionNumber>++;
}
loop<decisionNumber>:
;
} finally { DebugExitSubRule(<decisionNumber>); }
<@postloop()>
>>
positiveClosureBlockSingleAlt ::= positiveClosureBlock
/** A (..)* block with 1 or more alternatives */
closureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
// <fileName>:<description>
<decls>
<@preloop()>
try { DebugEnterSubRule(<decisionNumber>);
while (true)
{
int alt<decisionNumber>=<maxAlt>;
<@predecision()>
try { DebugEnterDecision(<decisionNumber>, decisionCanBacktrack[<decisionNumber>]);
<decision>
} finally { DebugExitDecision(<decisionNumber>); }
<@postdecision()>
switch ( alt<decisionNumber> )
{
<alts:{a|<altSwitchCase(i,a)>}>
default:
goto loop<decisionNumber>;
}
}
loop<decisionNumber>:
;
} finally { DebugExitSubRule(<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()>
DebugEnterAlt(<altNum>);
<alt>
break;<\n>
>>
/** An alternative is just a list of elements; at outermost level */
alt(elements,altNum,description,autoAST,outerAlt,treeLevel,rew) ::= <<
// <fileName>:<description>
{
<@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(it) ::= <%
<@prematch()>
DebugLocation(<it.line>, <it.pos>);<\n>
<it.el><\n>
%>
/** match a token optionally with a label in front */
tokenRef(token,label,elementIndex,terminalOptions) ::= <<
<if(label)><label>=(<labelType>)<endif>Match(input,<token>,Follow._<token>_in_<ruleName><elementIndex>); <checkRuleBacktrackFailure()>
>>
/** ids+=ID */
tokenRefAndListLabel(token,label,elementIndex,terminalOptions) ::= <<
<tokenRef(...)>
<listLabelElem(elem=label,elemType=labelType,...)>
>>
listLabelElem(label,elem,elemType) ::= <<
if (list_<label>==null) list_<label>=new List\<<elemType; null={<labelType>}>\>();
list_<label>.Add(<elem>);<\n>
>>
/** match a character */
charRef(char,label) ::= <<
<if(label)>
<label> = input.LA(1);<\n>
<endif>
Match(<char>); <checkRuleBacktrackFailure()>
>>
/** match a character range */
charRangeRef(a,b,label) ::= <<
<if(label)>
<label> = input.LA(1);<\n>
<endif>
MatchRange(<a>,<b>); <checkRuleBacktrackFailure()>
>>
/** For now, sets are interval tests and must be tested inline */
matchSet(s,label,terminalOptions,elementIndex,postmatchCode="") ::= <<
<if(label)>
<matchSetLabel()>
<endif>
if (<s>)
{
input.Consume();
<postmatchCode>
<if(!LEXER)>state.errorRecovery=false;<endif><if(backtracking)>state.failed=false;<endif>
}
else
{
<ruleBacktrackFailure()>
MismatchedSetException mse = new MismatchedSetException(null,input);
DebugRecognitionException(mse);
<@mismatchedSetException()>
<if(LEXER)>
Recover(mse);
throw mse;
<else>
throw mse;
<! use following code to make it recover inline; remove throw mse;
recoverFromMismatchedSet(input,mse,Follow._set_in_<ruleName><elementIndex>);
!>
<endif>
}<\n>
>>
matchSetUnchecked(s,label,elementIndex,postmatchCode=false) ::= <%
<if(label)>
<matchSetLabel()><\n>
<endif>
input.Consume();<\n>
<if(postmatchCode)>
<postmatchCode><\n>
<endif>
<if(!LEXER)>state.errorRecovery=false;<endif><if(backtracking)>state.failed=false;<endif>
%>
matchSetLabel() ::= <%
<if(LEXER)>
<label>= input.LA(1);
<else>
<label>=(<labelType>)input.LT(1);
<endif>
%>
matchRuleBlockSet ::= matchSet
matchSetAndListLabel(s,label,elementIndex,postmatchCode) ::= <<
<matchSet(...)>
<listLabelElem(elem=label,elemType=labelType,...)>
>>
/** Match a string literal */
lexerStringRef(string,label,elementIndex) ::= <%
<if(label)>
int <label>Start = CharIndex;<\n>
Match(<string>); <checkRuleBacktrackFailure()><\n>
int <label>StartLine<elementIndex> = Line;<\n>
int <label>StartCharPos<elementIndex> = CharPositionInLine;<\n>
<label> = new <labelType>(input, TokenTypes.Invalid, TokenChannels.Default, <label>Start, CharIndex-1);<\n>
<label>.Line = <label>StartLine<elementIndex>;<\n>
<label>.CharPositionInLine = <label>StartCharPos<elementIndex>;
<else>
Match(<string>); <checkRuleBacktrackFailure()><\n>
<endif>
%>
wildcard(token,label,elementIndex,terminalOptions) ::= <<
<if(label)>
<label>=(<labelType>)input.LT(1);<\n>
<endif>
MatchAny(input); <checkRuleBacktrackFailure()>
>>
wildcardAndListLabel(token,label,elementIndex,terminalOptions) ::= <<
<wildcard(...)>
<listLabelElem(elem=label,elemType=labelType,...)>
>>
/** Match . wildcard in lexer */
wildcardChar(label, elementIndex) ::= <<
<if(label)>
<label> = input.LA(1);<\n>
<endif>
MatchAny(); <checkRuleBacktrackFailure()>
>>
wildcardCharListLabel(label, elementIndex) ::= <<
<wildcardChar(...)>
<listLabelElem(elem=label,elemType=labelType,...)>
>>
/** 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) ::= <<
PushFollow(Follow._<rule.name>_in_<ruleName><elementIndex>);
<if(label)><label>=<endif><if(scope)><scope:delegateName()>.<endif><rule.name; format="id">(<args; separator=", ">);
PopFollow();
<checkRuleBacktrackFailure()>
>>
/** ids+=r */
ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
<ruleRef(...)>
<listLabelElem(elem=label,elemType={<ASTLabelType>},...)>
>>
/** 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)>
int <label>Start<elementIndex> = CharIndex;<\n>
int <label>StartLine<elementIndex> = Line;<\n>
int <label>StartCharPos<elementIndex> = CharPositionInLine;<\n>
<if(scope)><scope:delegateName()>.<endif>m<rule.name>(<args; separator=", ">); <checkRuleBacktrackFailure()><\n>
<label> = new <labelType>(input, TokenTypes.Invalid, TokenChannels.Default, <label>Start<elementIndex>, CharIndex-1);<\n>
<label>.Line = <label>StartLine<elementIndex>;<\n>
<label>.CharPositionInLine = <label>StartCharPos<elementIndex>;
<else>
<if(scope)><scope:delegateName()>.<endif>m<rule.name>(<args; separator=", ">); <checkRuleBacktrackFailure()>
<endif>
%>
/** i+=INT in lexer */
lexerRuleRefAndListLabel(rule,label,args,elementIndex,scope) ::= <<
<lexerRuleRef(...)>
<listLabelElem(elem=label,elemType=labelType,...)>
>>
/** EOF in the lexer */
lexerMatchEOF(label,elementIndex) ::= <%
<if(label)>
int <label>Start<elementIndex> = CharIndex;<\n>
int <label>StartLine<elementIndex> = Line;<\n>
int <label>StartCharPos<elementIndex> = CharPositionInLine;<\n>
Match(EOF); <checkRuleBacktrackFailure()><\n>
<labelType> <label> = new <labelType>(input, EOF, TokenChannels.Default, <label>Start<elementIndex>, CharIndex-1);<\n>
<label>.Line = <label>StartLine<elementIndex>;<\n>
<label>.CharPositionInLine = <label>StartCharPos<elementIndex>;
<else>
Match(EOF); <checkRuleBacktrackFailure()>
<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) == TokenTypes.Down)
{
Match(input, TokenTypes.Down, null); <checkRuleBacktrackFailure()>
<children:element()>
Match(input, TokenTypes.Up, null); <checkRuleBacktrackFailure()>
}
<else>
Match(input, TokenTypes.Down, null); <checkRuleBacktrackFailure()>
<children:element()>
Match(input, TokenTypes.Up, null); <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 new FailedPredicateException(input, "<ruleName>", "<description>");
}
>>
// F i x e d D F A (if-then-else)
dfaState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
int LA<decisionNumber>_<stateNumber> = input.LA(<k>);<\n>
<edges; separator="\nelse ">
else
{
<if(eotPredictsAlt)>
alt<decisionNumber> = <eotPredictsAlt>;
<else>
<ruleBacktrackFailure()>
NoViableAltException nvae = new NoViableAltException("<description>", <decisionNumber>, <stateNumber>, input);
DebugRecognitionException(nvae);
<@noViableAltException()>
throw nvae;
<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) ::= <<
int 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) ::= <<
int LA<decisionNumber>_<stateNumber> = input.LA(<k>);<\n>
<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) ::= <<
switch (input.LA(<k>))
{
<edges; separator="\n">
default:
<if(eotPredictsAlt)>
alt<decisionNumber>=<eotPredictsAlt>;
break;<\n>
<else>
{
<ruleBacktrackFailure()>
NoViableAltException nvae = new NoViableAltException("<description>", <decisionNumber>, <stateNumber>, input);
DebugRecognitionException(nvae);
<@noViableAltException()>
throw nvae;
}
<endif>
}<\n>
>>
dfaOptionalBlockStateSwitch(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
switch (input.LA(<k>))
{
<edges; separator="\n">
}<\n>
>>
dfaLoopbackStateSwitch(k, edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
switch (input.LA(<k>))
{
<edges; separator="\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) ::= <<
try
{
alt<decisionNumber> = dfa<decisionNumber>.Predict(input);
}
catch (NoViableAltException nvae)
{
DebugRecognitionException(nvae);
throw;
}
>>
/* 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) ::= <<
private class DFA<dfa.decisionNumber> : DFA
{
private const string DFA<dfa.decisionNumber>_eotS =
"<dfa.javaCompressedEOT; wrap="\"+\n\t\t\"">";
private const string DFA<dfa.decisionNumber>_eofS =
"<dfa.javaCompressedEOF; wrap="\"+\n\t\t\"">";
private const string DFA<dfa.decisionNumber>_minS =
"<dfa.javaCompressedMin; wrap="\"+\n\t\t\"">";
private const string DFA<dfa.decisionNumber>_maxS =
"<dfa.javaCompressedMax; wrap="\"+\n\t\t\"">";
private const string DFA<dfa.decisionNumber>_acceptS =
"<dfa.javaCompressedAccept; wrap="\"+\n\t\t\"">";
private const string DFA<dfa.decisionNumber>_specialS =
"<dfa.javaCompressedSpecial; wrap="\"+\n\t\t\"">}>";
private static readonly string[] DFA<dfa.decisionNumber>_transitionS =
{
<dfa.javaCompressedTransition:{s|"<s; wrap="\"+\n\"">"}; separator=",\n">
};
private static readonly short[] DFA<dfa.decisionNumber>_eot = DFA.UnpackEncodedString(DFA<dfa.decisionNumber>_eotS);
private static readonly short[] DFA<dfa.decisionNumber>_eof = DFA.UnpackEncodedString(DFA<dfa.decisionNumber>_eofS);
private static readonly char[] DFA<dfa.decisionNumber>_min = DFA.UnpackEncodedStringToUnsignedChars(DFA<dfa.decisionNumber>_minS);
private static readonly char[] DFA<dfa.decisionNumber>_max = DFA.UnpackEncodedStringToUnsignedChars(DFA<dfa.decisionNumber>_maxS);
private static readonly short[] DFA<dfa.decisionNumber>_accept = DFA.UnpackEncodedString(DFA<dfa.decisionNumber>_acceptS);
private static readonly short[] DFA<dfa.decisionNumber>_special = DFA.UnpackEncodedString(DFA<dfa.decisionNumber>_specialS);
private static readonly short[][] DFA<dfa.decisionNumber>_transition;
static DFA<dfa.decisionNumber>()
{
int numStates = DFA<dfa.decisionNumber>_transitionS.Length;
DFA<dfa.decisionNumber>_transition = new short[numStates][];
for ( int i=0; i \< numStates; i++ )
{
DFA<dfa.decisionNumber>_transition[i] = DFA.UnpackEncodedString(DFA<dfa.decisionNumber>_transitionS[i]);
}
}
public DFA<dfa.decisionNumber>( BaseRecognizer recognizer<if(dfa.specialStateSTs)>, SpecialStateTransitionHandler specialStateTransition<endif> )
<if(dfa.specialStateSTs)>
: base(specialStateTransition)
<endif>
{
this.recognizer = recognizer;
this.decisionNumber = <dfa.decisionNumber>;
this.eot = DFA<dfa.decisionNumber>_eot;
this.eof = DFA<dfa.decisionNumber>_eof;
this.min = DFA<dfa.decisionNumber>_min;
this.max = DFA<dfa.decisionNumber>_max;
this.accept = DFA<dfa.decisionNumber>_accept;
this.special = DFA<dfa.decisionNumber>_special;
this.transition = DFA<dfa.decisionNumber>_transition;
}
public override string Description { get { return "<dfa.description>"; } }
public override void Error(NoViableAltException nvae)
{
DebugRecognitionException(nvae);
}
}<\n>
<if(dfa.specialStateSTs)>
private int SpecialStateTransition<dfa.decisionNumber>(DFA dfa, int s, IIntStream _input)<! throws NoViableAltException!>
{
<if(LEXER)>
IIntStream input = _input;
<endif>
<if(PARSER)>
ITokenStream input = (ITokenStream)_input;
<endif>
<if(TREE_PARSER)>
ITreeNodeStream input = (ITreeNodeStream)_input;
<endif>
int _s = s;
switch (s)
{
<dfa.specialStateSTs:{state |
case <i0>:<! compressed special state numbers 0..n-1 !>
<state>}; separator="\n">
}
<if(backtracking)>
if (state.backtracking > 0) {state.failed=true; return -1;}
<endif>
NoViableAltException nvae = new NoViableAltException(dfa.Description, <dfa.decisionNumber>, _s, input);
dfa.Error(nvae);
throw nvae;
}
<endif>
>>
/** 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) ::= <<
int LA<decisionNumber>_<stateNumber> = input.LA(1);<\n>
<if(semPredState)>
<! get next lookahead symbol to test edges, then rewind !>
<\n>int index<decisionNumber>_<stateNumber> = input.Index;
input.Rewind();
<endif>
s = -1;
<edges; separator="\nelse ">
<if(semPredState)>
<! return input cursor to state before we rewound !>
<\n>input.Seek(index<decisionNumber>_<stateNumber>);
<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) ::= <<
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>
>>
// 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(...)>)"
evalPredicate(pred,description) ::= "(<pred>)"
evalSynPredicate(pred,description) ::= "EvaluatePredicate(<pred>_fragment)"
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><ge()><lower> && LA<decisionNumber>_<stateNumber><le()><upper>)
%>
isolatedLookaheadRangeTest(lower,upper,k,rangeNumber,lowerAsInt,upperAsInt) ::= "(input.LA(<k>)<ge()><lower> && input.LA(<k>)<le()><upper>)"
le() ::= "\<="
ge() ::= ">="
setTest(ranges) ::= <<
<ranges; separator="||">
>>
// A T T R I B U T E S
attributeScope(scope) ::= <<
<if(scope.attributes)>
protected sealed partial class <scope.name>_scope
{
<scope.attributes:{it|public <it.decl>;}; separator="\n">
}
<if(scope.actions.scopeinit)>
protected void <scope.name>_scopeInit( <scope.name>_scope scope )
{
<scope.actions.scopeinit>
}
<else>
protected virtual void <scope.name>_scopeInit( <scope.name>_scope scope ) {}
<endif>
<if(scope.actions.scopeafter)>
protected void <scope.name>_scopeAfter( <scope.name>_scope scope )
{
<scope.actions.scopeafter>
}
<else>
protected virtual void <scope.name>_scopeAfter( <scope.name>_scope scope ) {}
<endif>
protected readonly ListStack\<<scope.name>_scope\> <scope.name>_stack = new ListStack\<<scope.name>_scope\>();
<endif>
>>
globalAttributeScope(scope) ::= <<
<attributeScope(...)>
>>
ruleAttributeScope(scope) ::= <<
<attributeScope(...)>
>>
returnStructName(it) ::= "<it.name>_return"
returnType(ruleDescriptor) ::= <%
<if(ruleDescriptor.returnScope.attributes && ruleDescriptor.hasMultipleReturnValues)>
<ruleDescriptor.grammar.recognizerName>.<ruleDescriptor:returnStructName()>
<elseif(ruleDescriptor.hasMultipleReturnValues)>
<ruleReturnBaseType()>
<elseif(ruleDescriptor.hasSingleReturnValue)>
<ruleDescriptor.singleValueReturnType>
<else>
void
<endif>
%>
/** Generate the C# type associated with a single or multiple return
* values.
*/
ruleLabelType(referencedRule) ::= <%
<if(referencedRule.returnScope.attributes&&referencedRule.hasMultipleReturnValues)>
<referencedRule.grammar.recognizerName>.<referencedRule:returnStructName()>
<elseif(referencedRule.hasMultipleReturnValues)>
<ruleReturnBaseType()>
<elseif(referencedRule.hasSingleReturnValue)>
<referencedRule.singleValueReturnType>
<else>
void
<endif>
%>
delegateName(it) ::= <<
<if(it.label)><it.label><else>g<it.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) ::= <<
default(<typeName>)
>>
/** Define a rule label including default value */
ruleLabelDef(label) ::= <%
<ruleLabelType(referencedRule=label.referencedRule)> <label.label.text> = <initValue(typeName=ruleLabelType(referencedRule=label.referencedRule))>;
%>
/** 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.
*/
returnScope(scope) ::= <<
<if(scope.attributes && ruleDescriptor.hasMultipleReturnValues)>
<returnScopeModifier(grammar=grammar,ruleDescriptor=ruleDescriptor)> sealed partial class <ruleDescriptor:returnStructName()> : <ruleReturnBaseType()><@ruleReturnInterfaces()>
{
<scope.attributes:{it|public <it.decl>;}; separator="\n">
<@ruleReturnMembers()>
}
<endif>
>>
ruleReturnBaseType() ::= <%
<if(TREE_PARSER)>Tree<else>Parser<endif>RuleReturnScope\<<labelType>>
%>
@returnScope.ruleReturnMembers() ::= <<
>>
parameterScope(scope) ::= <<
<scope.attributes:{it|<it.decl>}; separator=", ">
>>
parameterAttributeRef(attr) ::= <<
<attr.name; format="id">
>>
parameterSetAttributeRef(attr,expr) ::= <<
<attr.name; format="id"> =<expr>;
>>
scopeAttributeRef(scope,attr,index,negIndex) ::= <%
<if(negIndex)>
<scope>_stack[<scope>_stack.Count - <negIndex> - 1].<attr.name; format="id">
<else>
<if(index)>
<scope>_stack[<index>].<attr.name; format="id">
<else>
<scope>_stack.Peek().<attr.name; format="id">
<endif>
<endif>
%>
scopeSetAttributeRef(scope,attr,expr,index,negIndex) ::= <%
<if(negIndex)>
<scope>_stack[<scope>_stack.Count - <negIndex> - 1].<attr.name; format="id"> = <expr>;
<else>
<if(index)>
<scope>_stack[<index>].<attr.name; format="id"> = <expr>;
<else>
<scope>_stack.Peek().<attr.name; format="id"> = <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.Count>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>!=null?<scope>.<attr.name; format="id">:<initValue(attr.type)>)
<else>
<scope>
<endif>
%>
returnAttributeRef(ruleDescriptor,attr) ::= <%
<if(ruleDescriptor.hasMultipleReturnValues)>
retval.<attr.name; format="id">
<else>
<attr.name; format="id">
<endif>
%>
returnSetAttributeRef(ruleDescriptor,attr,expr) ::= <%
<if(ruleDescriptor.hasMultipleReturnValues)>
retval.<attr.name; format="id"> =<expr>;
<else>
<attr.name; format="id"> =<expr>;
<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
tokenLabelPropertyRef_text(scope,attr) ::= "(<scope>!=null?<scope>.Text:null)"
tokenLabelPropertyRef_type(scope,attr) ::= "(<scope>!=null?<scope>.Type:0)"
tokenLabelPropertyRef_line(scope,attr) ::= "(<scope>!=null?<scope>.Line:0)"
tokenLabelPropertyRef_pos(scope,attr) ::= "(<scope>!=null?<scope>.CharPositionInLine:0)"
tokenLabelPropertyRef_channel(scope,attr) ::= "(<scope>!=null?<scope>.Channel:0)"
tokenLabelPropertyRef_index(scope,attr) ::= "(<scope>!=null?<scope>.TokenIndex:0)"
tokenLabelPropertyRef_tree(scope,attr) ::= "<scope>_tree"
tokenLabelPropertyRef_int(scope,attr) ::= "(<scope>!=null?int.Parse(<scope>.Text):0)"
ruleLabelPropertyRef_start(scope,attr) ::= "(<scope>!=null?((<labelType>)<scope>.Start):default(<labelType>))"
ruleLabelPropertyRef_stop(scope,attr) ::= "(<scope>!=null?((<labelType>)<scope>.Stop):default(<labelType>))"
ruleLabelPropertyRef_tree(scope,attr) ::= "(<scope>!=null?((<ASTLabelType>)<scope>.Tree):default(<ASTLabelType>))"
ruleLabelPropertyRef_text(scope,attr) ::= <%
<if(TREE_PARSER)>
(<scope>!=null?(input.TokenStream.ToString(
input.TreeAdaptor.GetTokenStartIndex(<scope>.Start),
input.TreeAdaptor.GetTokenStopIndex(<scope>.Start))):null)
<else>
(<scope>!=null?input.ToString(<scope>.Start,<scope>.Stop):null)
<endif>
%>
ruleLabelPropertyRef_st(scope,attr) ::= "(<scope>!=null?<scope>.Template:null)"
/** Isolated $RULE ref ok in lexer as it's a Token */
lexerRuleLabel(label) ::= "<label>"
lexerRuleLabelPropertyRef_type(scope,attr) ::=
"(<scope>!=null?<scope>.Type:0)"
lexerRuleLabelPropertyRef_line(scope,attr) ::=
"(<scope>!=null?<scope>.Line:0)"
lexerRuleLabelPropertyRef_pos(scope,attr) ::=
"(<scope>!=null?<scope>.CharPositionInLine:-1)"
lexerRuleLabelPropertyRef_channel(scope,attr) ::=
"(<scope>!=null?<scope>.Channel:0)"
lexerRuleLabelPropertyRef_index(scope,attr) ::=
"(<scope>!=null?<scope>.TokenIndex:0)"
lexerRuleLabelPropertyRef_text(scope,attr) ::=
"(<scope>!=null?<scope>.Text:null)"
lexerRuleLabelPropertyRef_int(scope,attr) ::=
"(<scope>!=null?int.Parse(<scope>.Text):0)"
// Somebody may ref $template or $tree or $stop within a rule:
rulePropertyRef_start(scope,attr) ::= "retval.Start"
rulePropertyRef_stop(scope,attr) ::= "retval.Stop"
rulePropertyRef_tree(scope,attr) ::= "retval.Tree"
rulePropertyRef_text(scope,attr) ::= <%
<if(TREE_PARSER)>
input.TokenStream.ToString(
input.TreeAdaptor.GetTokenStartIndex(retval.Start),
input.TreeAdaptor.GetTokenStopIndex(retval.Start))
<else>
input.ToString(retval.Start,input.LT(-1))
<endif>
%>
rulePropertyRef_st(scope,attr) ::= "retval.Template"
lexerRulePropertyRef_text(scope,attr) ::= "Text"
lexerRulePropertyRef_type(scope,attr) ::= "_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) ::= "(CharIndex-1)"
lexerRulePropertyRef_int(scope,attr) ::= "int.Parse(<scope>.Text)"
// setting $st and $tree is allowed in local rule. everything else
// is flagged as error
ruleSetPropertyRef_tree(scope,attr,expr) ::= "retval.Tree = <expr>;"
ruleSetPropertyRef_st(scope,attr,expr) ::= "retval.Template =<expr>;"
/** How to execute an action (only when not backtracking) */
execAction(action) ::= <%
<if(backtracking)>
if (<actions.(actionScope).synpredgate>)<\n>
{<\n>
<@indentedAction()><\n>
}
<else>
<action>
<endif>
%>
@execAction.indentedAction() ::= <<
<action>
>>
/** How to always execute an action even when backtracking */
execForcedAction(action) ::= "<action>"
// M I S C (properties, etc...)
bitset(name, words64) ::= <<
public static readonly BitSet <name> = new BitSet(new ulong[]{<words64:{it|<it>UL};separator=",">});
>>
codeFileExtension() ::= ".cs"
true_value() ::= "true"
false_value() ::= "false"