📄 csharp.stg
字号:
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;
<else>
<ruleBacktrackFailure()>
NoViableAltException nvae_d<decisionNumber>s<stateNumber> =
new NoViableAltException("<description>", <decisionNumber>, <stateNumber>, input);<\n>
<@noViableAltException()>
throw nvae_d<decisionNumber>s<stateNumber>;<\n>
<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"><\n>
<if(eotPredictsAlt)>
default:
alt<decisionNumber> = <eotPredictsAlt>;
break;<\n>
<endif>
}<\n>
>>
dfaEdgeSwitch(labels, targetState) ::= <<
<labels:{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);
>>
/* Dump DFA tables.
*/
cyclicDFA(dfa) ::= <<
static readonly short[] DFA<dfa.decisionNumber>_eot = {
<dfa.eot:{n|<n>}; null="-1", wrap="\n", separator=", ">
};
static readonly short[] DFA<dfa.decisionNumber>_eof = {
<dfa.eof:{n|<n>}; null="-1", wrap="\n", separator=", ">
};
static readonly int[] DFA<dfa.decisionNumber>_min = {
<dfa.min:{n|<n>}; null="0", wrap="\n", separator=", ">
};
static readonly int[] DFA<dfa.decisionNumber>_max = {
<dfa.max:{n|<n>}; null="0", wrap="\n", separator=", ">
};
static readonly short[] DFA<dfa.decisionNumber>_accept = {
<dfa.accept:{n|<n>}; null="-1", wrap="\n", separator=", ">
};
static readonly short[] DFA<dfa.decisionNumber>_special = {
<dfa.special:{n|<n>}; null="-1", wrap="\n", separator=", ">
};
static readonly short[] dfa<dfa.decisionNumber>_transition_null = null;
<dfa.edgeTransitionClassMap.keys:{table |
static readonly short[] dfa<dfa.decisionNumber>_transition<i0> = \{
<table; separator=", ", wrap="\n ", null="-1">
\};}>
static readonly short[][] DFA<dfa.decisionNumber>_transition = {
<dfa.transitionEdgeTables:{whichTable|dfa<dfa.decisionNumber>_transition<whichTable>}; null="_null", separator=",\n">
};
protected class DFA<dfa.decisionNumber> : DFA
{
public DFA<dfa.decisionNumber>(BaseRecognizer recognizer)
{
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;
}
override public string Description
{
get { return "<dfa.description>"; }
}
<@errorMethod()>
}<\n>
<if(dfa.specialStateSTs)>
protected internal int DFA<dfa.decisionNumber>_SpecialStateTransition(DFA dfa, int s, IIntStream input) //throws NoViableAltException
{
int _s = s;
switch ( s )
{
<dfa.specialStateSTs:{state |
case <i0> : <! compressed special state numbers 0..n-1 !>
<state>}; separator="\n">
}
<if(backtracking)>
if (backtracking > 0) {failed = true; return -1;}<\n>
<endif>
NoViableAltException nvae =
new NoViableAltException(dfa.Description, <dfa.decisionNumber>, _s, input);
dfa.Error(nvae);
throw nvae;
}<\n>
<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 !>
int 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) ::= <<
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) ::= "<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
globalAttributeScope(scope) ::= <<
<if(scope.attributes)>
protected class <scope.name>_scope
{
<scope.attributes:{protected internal <it.decl>;}; separator="\n">
}
protected Stack <scope.name>_stack = new Stack();<\n>
<endif>
>>
ruleAttributeScope(scope) ::= <<
<if(scope.attributes)>
protected class <scope.name>_scope
{
<scope.attributes:{protected internal <it.decl>;}; separator="\n">
}
protected Stack <scope.name>_stack = new Stack();<\n>
<endif>
>>
returnType() ::= <<
<if(ruleDescriptor.hasMultipleReturnValues)>
<ruleDescriptor.name>_return
<else>
<if(ruleDescriptor.hasSingleReturnValue)>
<ruleDescriptor.singleValueReturnType>
<else>
void
<endif>
<endif>
>>
/** Generate the C# type associated with a single or multiple return
* values.
*/
ruleLabelType(referencedRule) ::= <<
<if(referencedRule.hasMultipleReturnValues)>
<referencedRule.name>_return
<else>
<if(referencedRule.hasSingleReturnValue)>
<referencedRule.singleValueReturnType>
<else>
void
<endif>
<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) ::= <<
<csharpTypeInitMap.(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.
*/
returnScope(scope) ::= <<
<if(ruleDescriptor.hasMultipleReturnValues)>
public class <returnType()> : <if(TREE_PARSER)>Tree<else>Parser<endif>RuleReturnScope
{
<scope.attributes:{public <it.decl>;}; separator="\n">
<@ruleReturnMembers()>
};
<endif>
>>
parameterScope(scope) ::= <<
<scope.attributes:{<it.decl>}; separator=", ">
>>
parameterAttributeRef(attr) ::= "<attr.name>"
parameterSetAttributeRef(attr,expr) ::= "<attr.name> = <expr>;"
scopeAttributeRef(scope,attr,index,negIndex) ::= <<
<if(negIndex)>
((<scope>_scope)<scope>_stack[<scope>_stack.Count-<negIndex>-1]).<attr.name>
<else>
<if(index)>
((<scope>_scope)<scope>_stack[<index>]).<attr.name>
<else>
((<scope>_scope)<scope>_stack.Peek()).<attr.name>
<endif>
<endif>
>>
scopeSetAttributeRef(scope,attr,expr,index,negIndex) ::= <<
<if(negIndex)>
((<scope>_scope)<scope>_stack[<scope>_stack.Count-<negIndex>-1]).<attr.name> = <expr>;
<else>
<if(index)>
((<scope>_scope)<scope>_stack[<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>.<attr.name>
<else>
<scope>
<endif>
>>
returnAttributeRef(ruleDescriptor,attr) ::= <<
<if(ruleDescriptor.hasMultipleReturnValues)>
retval.<attr.name>
<else>
<attr.name>
<endif>
>>
returnSetAttributeRef(ruleDescriptor,attr,expr) ::= <<
<if(ruleDescriptor.hasMultipleReturnValues)>
retval.<attr.name> = <expr>;
<else>
<attr.name> = <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>.Text"
tokenLabelPropertyRef_type(scope,attr) ::= "<scope>.Type"
tokenLabelPropertyRef_line(scope,attr) ::= "<scope>.Line"
tokenLabelPropertyRef_pos(scope,attr) ::= "<scope>.CharPositionInLine"
tokenLabelPropertyRef_channel(scope,attr) ::= "<scope>.Channel"
tokenLabelPropertyRef_index(scope,attr) ::= "<scope>.TokenIndex"
tokenLabelPropertyRef_tree(scope,attr) ::= "<scope>_tree"
ruleLabelPropertyRef_start(scope,attr) ::= "((<labelType>)<scope>.start)"
ruleLabelPropertyRef_stop(scope,attr) ::= "((<labelType>)<scope>.stop)"
ruleLabelPropertyRef_tree(scope,attr) ::= "((<ASTLabelType>)<scope>.tree)"
ruleLabelPropertyRef_text(scope,attr) ::= <<
<if(TREE_PARSER)>
input.TokenStream.ToString(
input.TreeAdaptor.GetTokenStartIndex(<scope>.start),
input.TreeAdaptor.GetTokenStopIndex(<scope>.start) )
<else>
input.ToString(<scope>.start,<scope>.stop)
<endif>
>>
ruleLabelPropertyRef_st(scope,attr) ::= "<scope>.st"
/** Isolated $RULE ref ok in lexer as it's a Token */
lexerRuleLabel(label) ::= "<label>"
lexerRuleLabelPropertyRef_type(scope,attr) ::= "<scope>.Type"
lexerRuleLabelPropertyRef_line(scope,attr) ::= "<scope>.Line"
lexerRuleLabelPropertyRef_pos(scope,attr) ::= "<scope>.CharPositionInLine"
lexerRuleLabelPropertyRef_channel(scope,attr) ::= "<scope>.Channel"
lexerRuleLabelPropertyRef_index(scope,attr) ::= "<scope>.TokenIndex"
lexerRuleLabelPropertyRef_text(scope,attr) ::= "<scope>.Text"
// Somebody may ref $template or $tree or $stop within a rule:
rulePropertyRef_start(scope,attr) ::= "((<labelType>)retval.start)"
rulePropertyRef_stop(scope,attr) ::= "((<labelType>)retval.stop)"
rulePropertyRef_tree(scope,attr) ::= "((<ASTLabelType>)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.st"
lexerRulePropertyRef_text(scope,attr) ::= "Text"
lexerRulePropertyRef_type(scope,attr) ::= "_type"
lexerRulePropertyRef_line(scope,attr) ::= "tokenStartLine"
lexerRulePropertyRef_pos(scope,attr) ::= "tokenStartCharPositionInLine"
lexerRulePropertyRef_index(scope,attr) ::= "-1" // undefined token index in lexer
lexerRulePropertyRef_channel(scope,attr) ::= "channel"
lexerRulePropertyRef_start(scope,attr) ::= "tokenStartCharIndex"
lexerRulePropertyRef_stop(scope,attr) ::= "(CharIndex-1)"
// 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.st = <expr>;"
/** How to execute an action */
execAction(action) ::= <<
<if(backtracking)>
<if(actions.(actionScope).synpredgate)>
if ( <actions.(actionScope).synpredgate> )
{
<action>
}
<else>
if ( backtracking == 0 )
{
<action>
}
<endif>
<else>
<action>
<endif>
>>
// M I S C (properties, etc...)
bitset(name, words64) ::= <<
public static readonly BitSet <name> = new BitSet(new ulong[]{<words64:{<it>UL};separator=",">});<\n>
>>
codeFileExtension() ::= ".cs"
true() ::= "true"
false() ::= "false"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -