⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ruby.stg

📁 ANTLR(ANother Tool for Language Recognition)它是这样的一种工具
💻 STG
📖 第 1 页 / 共 3 页
字号:
# <description>def <ruleName>(<ruleDescriptor.parameterScope:parameterScope(scope=it)>)    <if(trace)>        puts " " * @indent + "<ruleName>"        @indent += 1    <endif>	<ruleDescriptor.actions.init>    <if(!ruleDescriptor.isSynPred)>    <if(ruleDescriptor.hasReturnValue)>    <if(ruleDescriptor.hasSingleReturnValue)>    <ruleDescriptor.singleValueReturnName> = nil    <endif>    <endif>    <endif>    <block>    <if(trace)>        @indent -= 1    <endif>    <if(!ruleDescriptor.isSynPred)>    <if(ruleDescriptor.hasReturnValue)>    <if(ruleDescriptor.hasSingleReturnValue)>    <ruleDescriptor.singleValueReturnName>    <endif>    <endif>    <endif>end>>/** How to generate a rule in the lexer; naked blocks are used for *  fragment rules. */lexerRule(ruleName,nakedBlock,ruleDescriptor,block,memoize) ::=<<def match_<ruleName>(<ruleDescriptor.parameterScope:parameterScope(scope=it)>)<if(nakedBlock)>    <block><\n><else>    start = @input.index    line = @input.line    column = @input.column    channel = nil    <block>    if @token.nil?        text = @input.substring(start, @input.index - 1)        @token = Token.new(:<ruleName>, line, column, text, channel)    end<\n><endif>end>>/** How to generate code for the implicitly-defined lexer grammar rule *  that chooses between lexer rules. */tokensRule(ruleName,nakedBlock,args,block,ruleDescriptor) ::=<<<lexerRule(...)>>>filteringNextToken() ::=<<    ---- filteringNextToken/ ---->>filteringActionGate() ::=<<    ---- filteringActionGate/ ---->>// S U B R U L E S/** A (...) subrule with multiple alternatives */block(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::=<<<switchBlock(...)>>>/** A rule block with multiple alternatives */ruleBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::=<<<switchBlock(...)>>>/** *  decision, decisionNumber don't seem to be relevant in this template *  alts actually has a single element */ruleBlockSingleAlt(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,description) ::=<<<plainBlock(...)>>>/** A special case of a (...) subrule with a single alternative */blockSingleAlt(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,description) ::=<<<plainBlock(...)>>>/** A (..)+ block with 0 or more alternatives */positiveClosureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::=<<# <description>matchedOnce<decisionNumber> = false<decls>while true    alt<decisionNumber> = <maxAlt>    <decision>    case alt<decisionNumber>        <alts:switchCase(); separator="\n">        else            break    end    matchedOnce<decisionNumber> = trueendif !matchedOnce<decisionNumber>    raise "Expected at least one match: <description>"end>>positiveClosureBlockSingleAlt  ::= positiveClosureBlock/** A (..)* block with 0 or more alternatives */closureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::=<<# <description><decls>while true    alt<decisionNumber> = <maxAlt>    <decision>    case alt<decisionNumber>        <alts:switchCase(); separator="\n">        else            break    endend>>closureBlockSingleAlt ::= closureBlock/** Optional blocks (x)? are translated to (x|) by before code generation *  so we can just use the normal block template */optionalBlock ::= blockoptionalBlockSingleAlt ::= block/** An alternative is just a list of elements; at outermost level */alt(elements,altNum,description,autoAST,outerAlt)::=<<# <description><elements: element(); separator="\n">>>// E L E M E N T S/** match a token optionally with a label in front */tokenRef(token,label,elementIndex)::=<<<if(label)>_<label> = @input.look_ahead(1)<\n><endif>match(:<token>)>>/** ids+=ID */tokenRefAndListLabel(token,label,elementIndex)::=<<<tokenRef(...)><listLabel(...)>>>listLabel(label)::=<<list_<label> ||= []list_<label> \<\< _<label>>>/** match a character */charRef(char,label)::=<<<if(label)>_<label> = <char><\n><endif>match(<char>)>>/** match a character range */charRangeRef(a,b)::=<<match_range(<a>, <b>)>>/** For now, sets are interval tests and must be tested inline */matchSet(s,label,elementIndex,postmatchCode)::=<<<if(label)>_<label> = <LA(1)><\n><endif>if <s>    <postmatchCode>    match()else    raise "Expected set"end>>matchSetAndListLabel(s,label,elementIndex,postmatchCode)::=<<<matchSet(...)><listLabel(...)>>>/** Match a string literal */lexerStringRef(string,label)::=<<<if(label)>_<label> = <string><\n><else>match(<string>)<\n><endif>>>wildcard(label, elementIndex)::=<<<if(label)>_<label> = <LA(1)><\n><endif>match()>>wildcardAndListLabel(label,elementIndex)::=<<<wildcard(...)><listLabel(...)>>>/** Match . wildcard in lexer */wildcardChar(label, elementIndex)::=<<<if(label)>_<label> = <LA(1)><\n><endif>match()>>wildcardCharListLabel(label, elementIndex)::=<<    ---- wildcardCharListLabel ----    label: <label>    elementIndex: <elementIndex>    ---- /wildcardCharListLabel ---->>/** Match a rule reference by invoking it possibly with arguments *  and a return value or values. */ruleRef(rule,label,elementIndex,args)::=<<<if(label)><label> = <rule>(<args; separator=", ">)<\n><else><rule>(<args; separator=", ">)<\n><endif>>>/** ids+=ID */ruleRefAndListLabel(rule,label,elementIndex,args)::=<<    ---- ruleRefAndListLabel ----    rule: <rule>    label: <label>    elementIndex: <elementIndex>    args: <args>    ---- /ruleRefAndListLabel ---->>/** A lexer rule reference */lexerRuleRef(rule,label,args)::=<<match_<rule>(<args; separator=", ">)>>/** EOF in the lexer */lexerMatchEOF(label)::=<<<if(label)>_<label> = :EOF<\n><endif>match(:EOF)>>/** match ^(root children) in tree parser */tree(root, children, nullableChildList)::=<<    ---- tree ----    root: <root>    children: <children>    nullableChildList: <nullableChildList>    ---- /tree ---->>/** Every predicate is used as a validating predicate (even when it is *  also hoisted into a prediction expression). */validateSemanticPredicate(pred,description)::=<<# <description>if !<evalPredicate(...)>    raise "Semantic predicate failed: #{<description>}"end>>// F i x e d  D F A  (if-then-else)dfaState(k,edges,eotPredictsAlt,description,stateNumber,semPredState)::=<<# <description>look_ahead<decisionNumber>_<stateNumber> = <LA(k)><if(LEXER)>look_ahead<decisionNumber>_<stateNumber> = -1 if look_ahead<decisionNumber>_<stateNumber> == :EOF<endif>if <edges; separator="\nelsif ">else<if(eotPredictsAlt)>    alt<decisionNumber> = <eotPredictsAlt><\n><else>    raise "Expected: <description>"<\n><endif>end>>/** 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. * *  If a semPredState, don't force lookahead lookup; preds might not *  need. */dfaOptionalBlockState(k,edges,eotPredictsAlt,description,stateNumber,semPredState)::=<<# <description>look_ahead<decisionNumber>_<stateNumber> = <LA(k)><if(LEXER)>look_ahead<decisionNumber>_<stateNumber> = -1 if look_ahead<decisionNumber>_<stateNumber> == :EOF<endif>if <edges; separator="\nelsif ">end>>/** 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. * *  If a semPredState, don't force lookahead lookup; preds might not *  need. */dfaLoopbackState(k,edges,eotPredictsAlt,description,stateNumber,semPredState)::=<<# <description>look_ahead<decisionNumber>_<stateNumber> = <LA(k)><if(LEXER)>look_ahead<decisionNumber>_<stateNumber> = -1 if look_ahead<decisionNumber>_<stateNumber> == :EOF<endif>if <edges; separator="\nelsif "><if(eotPredictsAlt)>else    alt<decisionNumber> = <eotPredictsAlt><endif>end>>/** An accept state indicates a unique alternative has been predicted *//** It is not clear that decisionNumber is available here */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)::=<<<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)::=<<# <description>case <LA(k)>    <edges; separator="\n">    else        <if(eotPredictsAlt)>        alt<decisionNumber> = <eotPredictsAlt><\n>        <else>        raise "Expected: <description>"<\n>        <endif>end>>/** * eotPredictsAlt is not relevant here */dfaOptionalBlockStateSwitch(k,edges,eotPredictsAlt,description,stateNumber,semPredState)::=<<# <description>case <LA(k)>    <edges; separator="\n">end>>dfaLoopbackStateSwitch(k, edges,eotPredictsAlt,description,stateNumber,semPredState)::=<<

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -