diff options
Diffstat (limited to 'tool/resources')
11 files changed, 4846 insertions, 0 deletions
diff --git a/tool/resources/org/antlr/v4/tool/templates/LeftRecursiveRules.stg b/tool/resources/org/antlr/v4/tool/templates/LeftRecursiveRules.stg new file mode 100644 index 0000000..f4085e2 --- /dev/null +++ b/tool/resources/org/antlr/v4/tool/templates/LeftRecursiveRules.stg @@ -0,0 +1,52 @@ +/* + * [The "BSD license"] + * Copyright (c) 2012 Terence Parr + * Copyright (c) 2012 Sam Harwell + * 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. + */ + +/** How to generate rules derived from left-recursive rules. + * These rely on recRuleAltPredicate(), + * recRuleArg(), recRuleSetResultAction(), recRuleSetReturnAction() + * templates in main language.stg + */ +group LeftRecursiveRules; + +recRule(ruleName, argName, primaryAlts, opAlts, setResultAction, + userRetvals, leftRecursiveRuleRefLabels) ::= +<< +<ruleName><if(userRetvals)> returns [<userRetvals>]<endif> + : ( {} <primaryAlts:{alt | <alt.altText> }; separator="\n | "> + ) + ( + <opAlts; separator="\n | "> + )* + ; +>> + +recRuleAlt(alt, precOption, opPrec, pred) ::= << +{<pred>}?\<<precOption>=<opPrec>\> <alt.altText> +>> diff --git a/tool/resources/org/antlr/v4/tool/templates/codegen/CSharp/CSharp.stg b/tool/resources/org/antlr/v4/tool/templates/codegen/CSharp/CSharp.stg new file mode 100644 index 0000000..81eb912 --- /dev/null +++ b/tool/resources/org/antlr/v4/tool/templates/codegen/CSharp/CSharp.stg @@ -0,0 +1,1096 @@ +/* + * [The "BSD license"] + * Copyright (c) 2013 Terence Parr + * Copyright (c) 2013 Sam Harwell + * 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. + */ + +// args must be <object-model-object>, <fields-resulting-in-STs> + +ParserFile(file, parser, namedActions) ::= << +<fileHeader(file.grammarFileName, file.ANTLRVersion)> +<if(file.genPackage)> +namespace <file.genPackage> { +<endif> +<namedActions.header> +using System; +using System.Text; +using System.Diagnostics; +using System.Collections.Generic; +using Antlr4.Runtime; +using Antlr4.Runtime.Atn; +using Antlr4.Runtime.Misc; +using Antlr4.Runtime.Tree; +using DFA = Antlr4.Runtime.Dfa.DFA; + +<parser> +<if(file.genPackage)> +} // namespace <file.genPackage> +<endif> +>> + +ListenerFile(file, header) ::= << +<fileHeader(file.grammarFileName, file.ANTLRVersion)> +<if(file.genPackage)> +namespace <file.genPackage> { +<endif> +<header> +using Antlr4.Runtime.Misc; +using IParseTreeListener = Antlr4.Runtime.Tree.IParseTreeListener; +using IToken = Antlr4.Runtime.IToken; + +/// \<summary> +/// This interface defines a complete listener for a parse tree produced by +/// \<see cref="<csIdentifier.(file.parserName)>"/>. +/// \</summary> +[System.CodeDom.Compiler.GeneratedCode("ANTLR", "<file.ANTLRVersion>")] +[System.CLSCompliant(false)] +public interface I<file.grammarName>Listener : IParseTreeListener { + <file.listenerNames:{lname | +/// \<summary> +<if(file.listenerLabelRuleNames.(lname))> +/// Enter a parse tree produced by the \<c><lname>\</c> +/// labeled alternative in \<see cref="<file.parserName>.<file.listenerLabelRuleNames.(lname)>"/>. +<else> +/// Enter a parse tree produced by \<see cref="<file.parserName>.<lname>"/>. +<endif> +/// \</summary> +/// \<param name="context">The parse tree.\</param> +void Enter<lname; format="cap">([NotNull] <csIdentifier.(file.parserName)>.<lname; format="cap">Context context); +/// \<summary> +<if(file.listenerLabelRuleNames.(lname))> +/// Exit a parse tree produced by the \<c><lname>\</c> +/// labeled alternative in \<see cref="<file.parserName>.<file.listenerLabelRuleNames.(lname)>"/>. +<else> +/// Exit a parse tree produced by \<see cref="<file.parserName>.<lname>"/>. +<endif> +/// \</summary> +/// \<param name="context">The parse tree.\</param> +void Exit<lname; format="cap">([NotNull] <csIdentifier.(file.parserName)>.<lname; format="cap">Context context);}; separator="\n"> +} +<if(file.genPackage)> +} // namespace <file.genPackage> +<endif> +>> + +BaseListenerFile(file, header) ::= << +<fileHeader(file.grammarFileName, file.ANTLRVersion)> +<if(file.genPackage)> +namespace <file.genPackage> { +<endif> +<header> + +using Antlr4.Runtime.Misc; +using IErrorNode = Antlr4.Runtime.Tree.IErrorNode; +using ITerminalNode = Antlr4.Runtime.Tree.ITerminalNode; +using IToken = Antlr4.Runtime.IToken; +using ParserRuleContext = Antlr4.Runtime.ParserRuleContext; + +/// \<summary> +/// This class provides an empty implementation of \<see cref="I<file.grammarName>Listener"/>, +/// which can be extended to create a listener which only needs to handle a subset +/// of the available methods. +/// \</summary> +[System.CodeDom.Compiler.GeneratedCode("ANTLR", "<file.ANTLRVersion>")] +[System.CLSCompliant(false)] +public partial class <file.grammarName>BaseListener : I<file.grammarName>Listener { + <file.listenerNames:{lname | +/// \<summary> +/// Enter a parse tree produced by \<see cref="<csIdentifier.(file.parserName)>.<csIdentifier.(lname)>"/>. +/// \<para>The default implementation does nothing.\</para> +/// \</summary> +/// \<param name="context">The parse tree.\</param> +public virtual void Enter<lname; format="cap">([NotNull] <csIdentifier.(file.parserName)>.<lname; format="cap">Context context) { \} +/// \<summary> +/// Exit a parse tree produced by \<see cref="<csIdentifier.(file.parserName)>.<csIdentifier.(lname)>"/>. +/// \<para>The default implementation does nothing.\</para> +/// \</summary> +/// \<param name="context">The parse tree.\</param> +public virtual void Exit<lname; format="cap">([NotNull] <csIdentifier.(file.parserName)>.<lname; format="cap">Context context) { \}}; separator="\n"> + + /// \<inheritdoc/> + /// \<remarks>The default implementation does nothing.\</remarks> + public virtual void EnterEveryRule([NotNull] ParserRuleContext context) { } + /// \<inheritdoc/> + /// \<remarks>The default implementation does nothing.\</remarks> + public virtual void ExitEveryRule([NotNull] ParserRuleContext context) { } + /// \<inheritdoc/> + /// \<remarks>The default implementation does nothing.\</remarks> + public virtual void VisitTerminal([NotNull] ITerminalNode node) { } + /// \<inheritdoc/> + /// \<remarks>The default implementation does nothing.\</remarks> + public virtual void VisitErrorNode([NotNull] IErrorNode node) { } +} +<if(file.genPackage)> +} // namespace <file.genPackage> +<endif> +>> + +VisitorFile(file, header) ::= << +<fileHeader(file.grammarFileName, file.ANTLRVersion)> +<if(file.genPackage)> +namespace <file.genPackage> { +<endif> +<header> +using Antlr4.Runtime.Misc; +using Antlr4.Runtime.Tree; +using IToken = Antlr4.Runtime.IToken; + +/// \<summary> +/// This interface defines a complete generic visitor for a parse tree produced +/// by \<see cref="<csIdentifier.(file.parserName)>"/>. +/// \</summary> +/// \<typeparam name="Result">The return type of the visit operation.\</typeparam> +[System.CodeDom.Compiler.GeneratedCode("ANTLR", "<file.ANTLRVersion>")] +[System.CLSCompliant(false)] +public interface I<file.grammarName>Visitor\<Result> : IParseTreeVisitor\<Result> { + <file.visitorNames:{lname | +/// \<summary> +<if(file.visitorLabelRuleNames.(lname))> +/// Visit a parse tree produced by the \<c><lname>\</c> +/// labeled alternative in \<see cref="<file.parserName>.<file.visitorLabelRuleNames.(lname)>"/>. +<else> +/// Visit a parse tree produced by \<see cref="<file.parserName>.<lname>"/>. +<endif> +/// \</summary> +/// \<param name="context">The parse tree.\</param> +/// \<return>The visitor result.\</return> +Result Visit<lname; format="cap">([NotNull] <csIdentifier.(file.parserName)>.<lname; format="cap">Context context);}; separator="\n"> +} +<if(file.genPackage)> +} // namespace <file.genPackage> +<endif> +>> + +BaseVisitorFile(file, header) ::= << +<fileHeader(file.grammarFileName, file.ANTLRVersion)> +<if(file.genPackage)> +namespace <file.genPackage> { +<endif> +<header> +using Antlr4.Runtime.Misc; +using Antlr4.Runtime.Tree; +using IToken = Antlr4.Runtime.IToken; +using ParserRuleContext = Antlr4.Runtime.ParserRuleContext; + +/// \<summary> +/// This class provides an empty implementation of \<see cref="I<file.grammarName>Visitor{Result}"/>, +/// which can be extended to create a visitor which only needs to handle a subset +/// of the available methods. +/// \</summary> +/// \<typeparam name="Result">The return type of the visit operation.\</typeparam> +[System.CodeDom.Compiler.GeneratedCode("ANTLR", "<file.ANTLRVersion>")] +[System.CLSCompliant(false)] +public partial class <file.grammarName>BaseVisitor\<Result> : AbstractParseTreeVisitor\<Result>, I<file.grammarName>Visitor\<Result> { + <file.visitorNames:{lname | +/// \<summary> +/// Visit a parse tree produced by \<see cref="<csIdentifier.(file.parserName)>.<csIdentifier.(lname)>"/>. +/// \<para> +/// The default implementation returns the result of calling \<see cref="AbstractParseTreeVisitor{Result\}.VisitChildren(IRuleNode)"/> +/// on \<paramref name="context"/>. +/// \</para> +/// \</summary> +/// \<param name="context">The parse tree.\</param> +/// \<return>The visitor result.\</return> +public virtual Result Visit<lname; format="cap">([NotNull] <csIdentifier.(file.parserName)>.<lname; format="cap">Context context) { return VisitChildren(context); \}}; separator="\n"> +} +<if(file.genPackage)> +} // namespace <file.genPackage> +<endif> +>> + +fileHeader(grammarFileName, ANTLRVersion) ::= << +//------------------------------------------------------------------------------ +// \<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> +//------------------------------------------------------------------------------ + +// Generated from <grammarFileName> by ANTLR <ANTLRVersion> + +// Unreachable code detected +#pragma warning disable 0162 +// The variable '...' is assigned but its value is never used +#pragma warning disable 0219 +// Missing XML comment for publicly visible type or member '...' +#pragma warning disable 1591 + +>> + +Parser(parser, funcs, atn, sempredFuncs, superClass) ::= << +<Parser_(ctor="parser_ctor", ...)> +>> + +Parser_(parser, funcs, atn, sempredFuncs, ctor, superClass) ::= << +[System.CodeDom.Compiler.GeneratedCode("ANTLR", "<file.ANTLRVersion>")] +[System.CLSCompliant(false)] +public partial class <csIdentifier.(parser.name)> : <superClass; null="Parser"> { + <if(parser.tokens)> + public const int + <parser.tokens:{k | <k>=<parser.tokens.(k)>}; separator=", ", wrap, anchor>; + <endif> + public const int + <parser.rules:{r | RULE_<r.name> = <r.index>}; separator=", ", wrap, anchor>; + public static readonly string[] ruleNames = { + <parser.ruleNames:{r | "<r>"}; separator=", ", wrap, anchor> + }; + + <vocabulary(parser.literalNames, parser.symbolicNames)> + + public override string GrammarFileName { get { return "<parser.grammarFileName>"; } } + + public override string[] RuleNames { get { return ruleNames; } } + + public override string SerializedAtn { get { return _serializedATN; } } + + <namedActions.members> + <parser:(ctor)()> + <funcs; separator="\n"> + +<if(sempredFuncs)> + public override bool Sempred(RuleContext _localctx, int ruleIndex, int predIndex) { + switch (ruleIndex) { + <parser.sempredFuncs.values:{f| +case <f.ruleIndex>: return <f.name>_sempred((<f.ctxType>)_localctx, predIndex);}; separator="\n"> + } + return true; + } + <sempredFuncs.values; separator="\n"> +<endif> + + <atn> +} +>> + +vocabulary(literalNames, symbolicNames) ::= << +private static readonly string[] _LiteralNames = { + <literalNames:{t | <t>}; null="null", separator=", ", wrap, anchor> +}; +private static readonly string[] _SymbolicNames = { + <symbolicNames:{t | <t>}; null="null", separator=", ", wrap, anchor> +}; +public static readonly IVocabulary DefaultVocabulary = new Vocabulary(_LiteralNames, _SymbolicNames); + +[NotNull] +public override IVocabulary Vocabulary +{ + get + { + return DefaultVocabulary; + } +} +>> + +dumpActions(recog, argFuncs, actionFuncs, sempredFuncs) ::= << +<if(actionFuncs)> +public override void Action(RuleContext _localctx, int ruleIndex, int actionIndex) { + switch (ruleIndex) { + <recog.actionFuncs.values:{f| +case <f.ruleIndex> : <f.name>_action(<if(!recog.modes)>(<f.ctxType>)<endif>_localctx, actionIndex); break;}; separator="\n"> + } +} +<actionFuncs.values; separator="\n"> +<endif> +<if(sempredFuncs)> +public override bool Sempred(RuleContext _localctx, int ruleIndex, int predIndex) { + switch (ruleIndex) { + <recog.sempredFuncs.values:{f| +case <f.ruleIndex> : return <f.name>_sempred(<if(!recog.modes)>(<f.ctxType>)<endif>_localctx, predIndex);}; separator="\n"> + } + return true; +} +<sempredFuncs.values; separator="\n"> +<endif> +>> + +parser_ctor(parser) ::= << +public <csIdentifier.(parser.name)>(ITokenStream input) + : base(input) +{ + Interpreter = new ParserATNSimulator(this,_ATN); +} +>> + +/* This generates a private method since the actionIndex is generated, making an + * overriding implementation impossible to maintain. + */ +RuleActionFunction(r, actions) ::= << +private void <r.name>_action(<r.ctxType> _localctx, int actionIndex) { + switch (actionIndex) { + <actions:{index| +case <index>: <actions.(index)> break;}; separator="\n"> + } +} +>> + +/* This generates a private method since the predIndex is generated, making an + * overriding implementation impossible to maintain. + */ +RuleSempredFunction(r, actions) ::= << +private bool <r.name>_sempred(<r.ctxType> _localctx, int predIndex) { + switch (predIndex) { + <actions:{index| +case <index>: return <actions.(index)>;}; separator="\n"> + } + return true; +} +>> + +RuleFunction(currentRule,args,code,locals,ruleCtx,altLabelCtxs,namedActions,finallyAction,postamble,exceptions) ::= << + +<if(ruleCtx)> +<ruleCtx> +<endif> +<altLabelCtxs:{l | <altLabelCtxs.(l)>}; separator="\n"> + +[RuleVersion(<namedActions.version; null="0">)] +<if(currentRule.modifiers)><currentRule.modifiers:{f | <f> }><else>public <endif><currentRule.ctxType> <csIdentifier.(currentRule.name)>(<args; separator=", ">) { + <currentRule.ctxType> _localctx = new <currentRule.ctxType>(Context, State<currentRule.args:{a | , <csIdentifier.(a.name)>}>); + EnterRule(_localctx, <currentRule.startState>, RULE_<currentRule.name>); + <namedActions.init> + <locals; separator="\n"> + try { +<if(currentRule.hasLookaheadBlock)> + int _alt; +<endif> + <code> + <postamble; separator="\n"> + <namedActions.after> + } + <if(exceptions)> + <exceptions; separator="\n"> + <else> + catch (RecognitionException re) { + _localctx.exception = re; + ErrorHandler.ReportError(this, re); + ErrorHandler.Recover(this, re); + } + <endif> + finally { + <finallyAction> + ExitRule(); + } + return _localctx; +} +>> + +LeftFactoredRuleFunction(currentRule,args,code,locals,namedActions,finallyAction,postamble) ::= +<< + +<if(currentRule.modifiers)><currentRule.modifiers:{f | <f> }><else>private <endif><currentRule.ctxType> <csIdentifier.(currentRule.name)>(<args; separator=", ">) { + <currentRule.ctxType> _localctx = new <currentRule.ctxType>(Context, State<currentRule.args:{a | , <csIdentifier.(a.name)>}>); + EnterLeftFactoredRule(_localctx, <currentRule.startState>, RULE_<currentRule.variantOf>); + <namedActions.init> + <locals; separator="\n"> + try { +<if(currentRule.hasLookaheadBlock)> + int _alt; +<endif> + <code> + <postamble; separator="\n"> + <namedActions.after> + } + catch (RecognitionException re) { + _localctx.exception = re; + ErrorHandler.ReportError(this, re); + ErrorHandler.Recover(this, re); + } + finally { + <finallyAction> + ExitRule(); + } + return _localctx; +} +>> + +// This behaves similar to RuleFunction (enterRule is called, and no adjustments +// are made to the parse tree), but since it's still a variant no context class +// needs to be generated. +LeftUnfactoredRuleFunction(currentRule,args,code,locals,namedActions,finallyAction,postamble) ::= +<< + +<if(currentRule.modifiers)><currentRule.modifiers:{f | <f> }><else>private <endif><currentRule.ctxType> <csIdentifier.(currentRule.name)>(<args; separator=", ">) { + <currentRule.ctxType> _localctx = new <currentRule.ctxType>(Context, State<currentRule.args:{a | , <csIdentifier.(a.name)>}>); + EnterRule(_localctx, <currentRule.startState>, RULE_<currentRule.variantOf>); + <namedActions.init> + <locals; separator="\n"> + try { +<if(currentRule.hasLookaheadBlock)> + int _alt; +<endif> + <code> + <postamble; separator="\n"> + <namedActions.after> + } + catch (RecognitionException re) { + _localctx.exception = re; + ErrorHandler.ReportError(this, re); + ErrorHandler.Recover(this, re); + } + finally { + <finallyAction> + ExitRule(); + } + return _localctx; +} +>> + +LeftRecursiveRuleFunction(currentRule,args,code,locals,ruleCtx,altLabelCtxs, + namedActions,finallyAction,postamble) ::= +<< + +<ruleCtx> +<altLabelCtxs:{l | <altLabelCtxs.(l)>}; separator="\n"> + +[RuleVersion(<namedActions.version; null="0">)] +<if(currentRule.modifiers)><currentRule.modifiers:{f | <f> }><else>public <endif><currentRule.ctxType> <csIdentifier.(currentRule.name)>(<args; separator=", ">) { + return <csIdentifier.(currentRule.name)>(0<currentRule.args:{a | , <csIdentifier.(a.name)>}>); +} + +private <currentRule.ctxType> <csIdentifier.(currentRule.name)>(int _p<args:{a | , <a>}>) { + ParserRuleContext _parentctx = Context; + int _parentState = State; + <currentRule.ctxType> _localctx = new <currentRule.ctxType>(Context, _parentState<currentRule.args:{a | , <csIdentifier.(a.name)>}>); + <currentRule.ctxType> _prevctx = _localctx; + int _startState = <currentRule.startState>; + EnterRecursionRule(_localctx, <currentRule.startState>, RULE_<currentRule.name>, _p); + <namedActions.init> + <locals; separator="\n"> + try { +<if(currentRule.hasLookaheadBlock)> + int _alt; +<endif> + <code> + <postamble; separator="\n"> + <namedActions.after> + } + catch (RecognitionException re) { + _localctx.exception = re; + ErrorHandler.ReportError(this, re); + ErrorHandler.Recover(this, re); + } + finally { + <finallyAction> + UnrollRecursionContexts(_parentctx); + } + return _localctx; +} +>> + +CodeBlockForOuterMostAlt(currentOuterMostAltCodeBlock, locals, preamble, ops) ::= << +<if(currentOuterMostAltCodeBlock.altLabel)>_localctx = new <currentOuterMostAltCodeBlock.altLabel; format="cap">Context(_localctx);<endif> +EnterOuterAlt(_localctx, <currentOuterMostAltCodeBlock.alt.altNum>); +<CodeBlockForAlt(currentAltCodeBlock=currentOuterMostAltCodeBlock, ...)> +>> + +CodeBlockForAlt(currentAltCodeBlock, locals, preamble, ops) ::= << +{ +<locals; separator="\n"> +<preamble; separator="\n"> +<ops; separator="\n"> +} +>> + +LL1AltBlock(choice, preamble, alts, error) ::= << +State = <choice.stateNumber>; +<!ErrorHandler.sync(this);!> +<if(choice.label)><labelref(choice.label)> = TokenStream.Lt(1);<endif> +<preamble; separator="\n"> +switch (TokenStream.La(1)) { +<choice.altLook,alts:{look,alt| <cases(ttypes=look)> + <alt> + break;}; separator="\n"> +default: + <error> +} +>> + +LL1OptionalBlock(choice, alts, error) ::= << +State = <choice.stateNumber>; +<!ErrorHandler.sync(this);!> +switch (TokenStream.La(1)) { +<choice.altLook,alts:{look,alt| <cases(ttypes=look)> + <alt> + break;}; separator="\n"> +default: + <error> +} +>> + +LL1OptionalBlockSingleAlt(choice, expr, alts, preamble, error, followExpr) ::= << +State = <choice.stateNumber>; +<!ErrorHandler.sync(this);!> +<preamble; separator="\n"> +if (<expr>) { + <alts; separator="\n"> +} +<!else if ( !(<followExpr>) ) <error>!> +>> + +LL1StarBlockSingleAlt(choice, loopExpr, alts, preamble, iteration) ::= << +State = <choice.stateNumber>; +ErrorHandler.Sync(this); +<preamble; separator="\n"> +while (<loopExpr>) { + <alts; separator="\n"> + State = <choice.loopBackStateNumber>; + ErrorHandler.Sync(this); + <iteration> +} +>> + +LL1PlusBlockSingleAlt(choice, loopExpr, alts, preamble, iteration) ::= << +State = <choice.blockStartStateNumber>;<! alt block decision !> +ErrorHandler.Sync(this); +<preamble; separator="\n"> +do { + <alts; separator="\n"> + State = <choice.stateNumber>;<! loopback/exit decision !> + ErrorHandler.Sync(this); + <iteration> +} while ( <loopExpr> ); +>> + +// LL(*) stuff + +AltBlock(choice, preamble, alts, error) ::= << +State = <choice.stateNumber>; +<!ErrorHandler.sync(this);!> +<if(choice.label)><labelref(choice.label)> = TokenStream.Lt(1);<endif> +<preamble; separator="\n"> +switch ( Interpreter.AdaptivePredict(TokenStream,<choice.decision>,Context) ) { +<alts:{alt | +case <i>: + <alt> + break;}; separator="\n"> +} +>> + +OptionalBlock(choice, alts, error) ::= << +State = <choice.stateNumber>; +<!ErrorHandler.sync(this);!> +switch ( Interpreter.AdaptivePredict(TokenStream,<choice.decision>,Context) ) { +<alts:{alt | +case <i><if(!choice.ast.greedy)>+1<endif>: + <alt> + break;}; separator="\n"> +} +>> + +StarBlock(choice, alts, sync, iteration) ::= << +State = <choice.stateNumber>; +ErrorHandler.Sync(this); +_alt = Interpreter.AdaptivePredict(TokenStream,<choice.decision>,Context); +while ( _alt!=<choice.exitAlt> && _alt!=global::Antlr4.Runtime.Atn.ATN.InvalidAltNumber ) { + if ( _alt==1<if(!choice.ast.greedy)>+1<endif> ) { + <iteration> + <alts> <! should only be one !> + } + State = <choice.loopBackStateNumber>; + ErrorHandler.Sync(this); + _alt = Interpreter.AdaptivePredict(TokenStream,<choice.decision>,Context); +} +>> + +PlusBlock(choice, alts, error) ::= << +State = <choice.blockStartStateNumber>;<! alt block decision !> +ErrorHandler.Sync(this); +_alt = 1<if(!choice.ast.greedy)>+1<endif>; +do { + switch (_alt) { + <alts:{alt| +case <i><if(!choice.ast.greedy)>+1<endif>: + <alt> + break;}; separator="\n"> + default: + <error> + } + State = <choice.loopBackStateNumber>;<! loopback/exit decision !> + ErrorHandler.Sync(this); + _alt = Interpreter.AdaptivePredict(TokenStream,<choice.decision>,Context); +} while ( _alt!=<choice.exitAlt> && _alt!=global::Antlr4.Runtime.Atn.ATN.InvalidAltNumber ); +>> + +Sync(s) ::= "Sync(<s.expecting.name>);" + +ThrowNoViableAlt(t) ::= "throw new NoViableAltException(this);" + +TestSetInline(s) ::= << +<s.bitsets:{bits | <if(rest(rest(bits.ttypes)))><bitsetBitfieldComparison(s, bits)><else><bitsetInlineComparison(s, bits)><endif>}; separator=" || "> +>> + +// Java language spec 15.19 - shift operators mask operands rather than overflow to 0... need range test +testShiftInRange(shiftAmount) ::= << +((<shiftAmount>) & ~0x3f) == 0 +>> + +// produces smaller bytecode only when bits.ttypes contains more than two items +bitsetBitfieldComparison(s, bits) ::= <% +(<testShiftInRange({<offsetShift(s.varName, bits.shift)>})> && ((1L \<\< <offsetShift(s.varName, bits.shift)>) & (<bits.ttypes:{ttype | (1L \<\< <offsetShift(tokenType.(ttype), bits.shift)>)}; separator=" | ">)) != 0) +%> + +isZero ::= [ +"0":true, +default:false +] + +offsetShift(shiftAmount, offset) ::= <% +<if(!isZero.(offset))>(<shiftAmount> - <offset>)<else><shiftAmount><endif> +%> + +// produces more efficient bytecode when bits.ttypes contains at most two items +bitsetInlineComparison(s, bits) ::= <% +<bits.ttypes:{ttype | <s.varName>==<tokenType.(ttype)>}; separator=" || "> +%> + +cases(ttypes) ::= << +<ttypes:{t | case <tokenType.(t)>:}; separator="\n"> +>> + +InvokeRule(r, argExprsChunks) ::= << +State = <r.stateNumber>; <if(r.labels)><r.labels:{l | <labelref(l)> = }><endif><csIdentifier.(r.name)>(<if(r.ast.options.p)><r.ast.options.p><if(argExprsChunks)>,<endif><endif><argExprsChunks>); +>> + +MatchToken(m) ::= << +State = <m.stateNumber>; <if(m.labels)><m.labels:{l | <labelref(l)> = }><endif>Match(<tokenType.(m.name)>); +>> + +MatchSet(m, expr, capture) ::= "<CommonSetStuff(m, expr, capture, false)>" + +MatchNotSet(m, expr, capture) ::= "<CommonSetStuff(m, expr, capture, true)>" + +CommonSetStuff(m, expr, capture, invert) ::= << +State = <m.stateNumber>; +<if(m.labels)><m.labels:{l | <labelref(l)> = }>TokenStream.Lt(1);<endif> +<capture> +if ( <if(invert)><m.varName> \<= 0 || <else>!<endif>(<expr>) ) { + <if(m.labels)><m.labels:{l | <labelref(l)> = }><endif>ErrorHandler.RecoverInline(this); +} +else { + Consume(); +} +>> + +Wildcard(w) ::= << +State = <w.stateNumber>; +<if(w.labels)><w.labels:{l | <labelref(l)> = }><endif>MatchWildcard(); +>> + +// ACTION STUFF + +Action(a, foo, chunks) ::= "<chunks>" + +ArgAction(a, chunks) ::= "<chunks>" + +SemPred(p, chunks, failChunks) ::= << +State = <p.stateNumber>; +if (!(<chunks>)) throw new FailedPredicateException(this, <p.predicate><if(failChunks)>, <failChunks><elseif(p.msg)>, <p.msg><endif>); +>> + +ExceptionClause(e, catchArg, catchAction) ::= << +catch (<catchArg>) { + <catchAction> +} +>> + +// lexer actions are not associated with model objects + +LexerSkipCommand() ::= "Skip();" +LexerMoreCommand() ::= "More();" +LexerPopModeCommand() ::= "PopMode();" + +LexerTypeCommand(arg) ::= "_type = <tokenType.(arg)>;" +LexerChannelCommand(arg) ::= "_channel = <channelName.(arg)>;" +LexerModeCommand(arg) ::= "_mode = <modeName.(arg)>;" +LexerPushModeCommand(arg) ::= "PushMode(<modeName.(arg)>);" + +ActionText(t) ::= "<t.text>" +ActionTemplate(t) ::= "<t.st>" +ArgRef(a) ::= "_localctx.<csIdentifier.(a.name)>" +LocalRef(a) ::= "_localctx.<csIdentifier.(a.name)>" +RetValueRef(a) ::= "_localctx.<csIdentifier.(a.name)>" +QRetValueRef(a) ::= "<ctx(a)>.<a.dict>.<csIdentifier.(a.name)>" +/** How to translate $tokenLabel */ +TokenRef(t) ::= "<ctx(t)>.<csIdentifier.(tokenType.(t.name))>" +LabelRef(t) ::= "<ctx(t)>.<csIdentifier.(t.name)>" +ListLabelRef(t) ::= "<ctx(t)>.<ListLabelName(csIdentifier.(t.name))>" +SetAttr(s,rhsChunks) ::= "<ctx(s)>.<csIdentifier.(s.name)> = <rhsChunks>;" + +TokenLabelType() ::= "<file.TokenLabelType; null={IToken}>" +InputSymbolType() ::= "<file.InputSymbolType; null={IToken}>" + +TokenPropertyRef_text(t) ::= "(<ctx(t)>.<tokenType.(t.label)>!=null?<ctx(t)>.<tokenType.(t.label)>.Text:null)" +TokenPropertyRef_type(t) ::= "(<ctx(t)>.<tokenType.(t.label)>!=null?<ctx(t)>.<tokenType.(t.label)>.Type:0)" +TokenPropertyRef_line(t) ::= "(<ctx(t)>.<tokenType.(t.label)>!=null?<ctx(t)>.<tokenType.(t.label)>.Line:0)" +TokenPropertyRef_pos(t) ::= "(<ctx(t)>.<tokenType.(t.label)>!=null?<ctx(t)>.<tokenType.(t.label)>.CharPositionInLine:0)" +TokenPropertyRef_channel(t) ::= "(<ctx(t)>.<tokenType.(t.label)>!=null?<ctx(t)>.<tokenType.(t.label)>.Channel:0)" +TokenPropertyRef_index(t) ::= "(<ctx(t)>.<tokenType.(t.label)>!=null?<ctx(t)>.<tokenType.(t.label)>.TokenIndex:0)" +TokenPropertyRef_int(t) ::= "(<ctx(t)>.<tokenType.(t.label)>!=null?int.Parse(<ctx(t)>.<tokenType.(t.label)>.Text):0)" + +RulePropertyRef_start(r) ::= "(<ctx(r)>.<r.label>!=null?(<ctx(r)>.<r.label>.Start):null)" +RulePropertyRef_stop(r) ::= "(<ctx(r)>.<r.label>!=null?(<ctx(r)>.<r.label>.Stop):null)" +RulePropertyRef_text(r) ::= "(<ctx(r)>.<r.label>!=null?TokenStream.GetText(<ctx(r)>.<r.label>.Start,<ctx(r)>.<r.label>.Stop):null)" +RulePropertyRef_ctx(r) ::= "<ctx(r)>.<r.label>" +RulePropertyRef_parser(r) ::= "this" + +ThisRulePropertyRef_start(r) ::= "_localctx.Start" +ThisRulePropertyRef_stop(r) ::= "_localctx.Stop" +ThisRulePropertyRef_text(r) ::= "TokenStream.GetText(_localctx.Start, TokenStream.Lt(-1))" +ThisRulePropertyRef_ctx(r) ::= "_localctx" +ThisRulePropertyRef_parser(r) ::= "this" + +NonLocalAttrRef(s) ::= <%((<s.ruleName; format="cap">Context)GetInvokingContext(<s.ruleIndex>)).<csIdentifier.(s.name)>%> +SetNonLocalAttr(s, rhsChunks) ::= + <%((<s.ruleName; format="cap">Context)GetInvokingContext(<s.ruleIndex>)).<csIdentifier.(s.name)> = <rhsChunks>;%> + +AddToLabelList(a) ::= "<ctx(a.label)>.<a.listName>.Add(<labelref(a.label)>);" + +TokenDecl(t) ::= "<TokenLabelType()> <csIdentifier.(tokenType.(t.name))>" +TokenTypeDecl(t) ::= "int <csIdentifier.(tokenType.(t.name))>;" +TokenListDecl(t) ::= "IList\<IToken> <csIdentifier.(tokenType.(t.name))> = new List\<IToken>()" +RuleContextDecl(r) ::= "<r.ctxName> <csIdentifier.(r.name)>" +RuleContextListDecl(rdecl) ::= "IList\<<rdecl.ctxName>> <csIdentifier.(rdecl.name)> = new List\<<rdecl.ctxName>>()" + +contextGetterCollection(elementType) ::= <% +<elementType>[] +%> + +ContextTokenGetterDecl(t) ::= + "public ITerminalNode <csIdentifier.(tokenType.(t.name))>() { return GetToken(<csIdentifier.(parser.name)>.<csIdentifier.(tokenType.(t.name))>, 0); }" +ContextTokenListGetterDecl(t) ::= << +public <contextGetterCollection("ITerminalNode")> <csIdentifier.(tokenType.(t.name))>() { return GetTokens(<csIdentifier.(parser.name)>.<csIdentifier.(tokenType.(t.name))>); } +>> +ContextTokenListIndexedGetterDecl(t) ::= << +public ITerminalNode <csIdentifier.(tokenType.(t.name))>(int i) { + return GetToken(<csIdentifier.(parser.name)>.<csIdentifier.(tokenType.(t.name))>, i); +} +>> +ContextRuleGetterDecl(r) ::= << +public <r.ctxName> <csIdentifier.(r.name)>() { + return GetRuleContext\<<r.ctxName>\>(0); +} +>> +ContextRuleListGetterDecl(r) ::= << +public <contextGetterCollection({<r.ctxName>})> <csIdentifier.(r.name)>() { + return GetRuleContexts\<<r.ctxName>\>(); +} +>> +ContextRuleListIndexedGetterDecl(r) ::= << +public <r.ctxName> <csIdentifier.(r.name)>(int i) { + return GetRuleContext\<<r.ctxName>\>(i); +} +>> + +LexerRuleContext() ::= "RuleContext" + +/** The rule context name is the rule followed by a suffix; e.g., + * r becomes rContext. + */ +RuleContextNameSuffix() ::= "Context" + +ImplicitTokenLabel(tokenName) ::= "_<tokenType.(tokenName)>" +ImplicitRuleLabel(ruleName) ::= "_<ruleName>" +ImplicitSetLabel(id) ::= "_tset<id>" +ListLabelName(label) ::= "_<label>" + +CaptureNextToken(d) ::= "<d.varName> = TokenStream.Lt(1);" +CaptureNextTokenType(d) ::= "<d.varName> = TokenStream.La(1);" + +StructDecl(struct,ctorAttrs,attrs,getters,dispatchMethods,interfaces,extensionMembers, + superClass={ParserRuleContext}) ::= << +public partial class <struct.name> : <superClass><if(interfaces)>, <interfaces; separator=", "><endif> { + <attrs:{a | public <a>;}; separator="\n"> + <getters:{g | <g>}; separator="\n"> + <if(ctorAttrs)>public <struct.name>(ParserRuleContext parent, int invokingState) : base(parent, invokingState) { }<endif> + public <struct.name>(ParserRuleContext parent, int invokingState<ctorAttrs:{a | , <a>}>) + : base(parent, invokingState) + { + <struct.ctorAttrs:{a | this.<csIdentifier.(a.name)> = <csIdentifier.(a.name)>;}; separator="\n"> + } + public override int RuleIndex { get { return RULE_<struct.derivedFromName>; } } +<if(struct.provideCopyFrom)> <! don't need copy unless we have subclasses !> + public <struct.name>() { } + public virtual void CopyFrom(<struct.name> context) { + base.CopyFrom(context); + <struct.attrs:{a | this.<csIdentifier.(a.name)> = context.<csIdentifier.(a.name)>;}; separator="\n"> + } +<endif> + <dispatchMethods; separator="\n"> + <extensionMembers; separator="\n"> +} +>> + +AltLabelStructDecl(struct,attrs,getters,dispatchMethods) ::= << +public partial class <struct.name> : <currentRule.name; format="cap">Context { + <attrs:{a | public <a>;}; separator="\n"> + <getters:{g | <g>}; separator="\n"> + public <struct.name>(<currentRule.name; format="cap">Context context) { CopyFrom(context); } + <dispatchMethods; separator="\n"> +} +>> + +ListenerDispatchMethod(method) ::= << +public override void <if(method.isEnter)>Enter<else>Exit<endif>Rule(IParseTreeListener listener) { + I<parser.grammarName>Listener typedListener = listener as I<parser.grammarName>Listener; + if (typedListener != null) typedListener.<if(method.isEnter)>Enter<else>Exit<endif><struct.derivedFromName; format="cap">(this); +} +>> + +VisitorDispatchMethod(method) ::= << +public override TResult Accept\<TResult>(IParseTreeVisitor\<TResult> visitor) { + I<parser.grammarName>Visitor\<TResult> typedVisitor = visitor as I<parser.grammarName>Visitor\<TResult>; + if (typedVisitor != null) return typedVisitor.Visit<struct.derivedFromName; format="cap">(this); + else return visitor.VisitChildren(this); +} +>> + +AttributeDecl(d) ::= "<d.type> <csIdentifier.(d.name)><if(d.initValue)> = <d.initValue><endif>" + +/** If we don't know location of label def x, use this template */ +labelref(x) ::= "<if(!x.isLocal)><typedContext(x.ctx)>.<endif><csIdentifier.(x.name)>" + +/** For any action chunk, what is correctly-typed context struct ptr? */ +ctx(actionChunk) ::= "<typedContext(actionChunk.ctx)>" + +// only casts _localctx to the type when the cast isn't redundant (i.e. to a sub-context for a labeled alt) +typedContext(ctx) ::= "<if(ctx.provideCopyFrom)>((<ctx.name>)_localctx)<else>_localctx<endif>" + +// used for left-recursive rules +recRuleAltPredicate(ruleName,opPrec) ::= "Precpred(Context, <opPrec>)" +recRuleSetReturnAction(src,name) ::= "$<name>=$<src>.<name>;" +recRuleSetStopToken() ::= "Context.Stop = TokenStream.Lt(-1);" + +recRuleAltStartAction(ruleName, ctxName, label, isListLabel) ::= << +_localctx = new <ctxName>Context(_parentctx, _parentState); +<if(label)> +<if(isListLabel)> +_localctx.<label>.Add(_prevctx); +<else> +_localctx.<label> = _prevctx; +<endif> +<endif> +PushNewRecursionContext(_localctx, _startState, RULE_<ruleName>); +>> + +recRuleLabeledAltStartAction(ruleName, currentAltLabel, label, isListLabel) ::= << +_localctx = new <currentAltLabel; format="cap">Context(new <ruleName; format="cap">Context(_parentctx, _parentState)); +<if(label)> +<if(isListLabel)> +((<currentAltLabel; format="cap">Context)_localctx).<label>.Add(_prevctx); +<else> +((<currentAltLabel; format="cap">Context)_localctx).<label> = _prevctx; +<endif> +<endif> +PushNewRecursionContext(_localctx, _startState, RULE_<ruleName>); +>> + +recRuleReplaceContext(ctxName) ::= << +_localctx = new <ctxName>Context(_localctx); +Context = _localctx; +_prevctx = _localctx; +>> + +recRuleSetPrevCtx() ::= << +if ( ParseListeners!=null ) + TriggerExitRuleEvent(); +_prevctx = _localctx; +>> + + +LexerFile(file, lexer, namedActions) ::= << +<fileHeader(file.grammarFileName, file.ANTLRVersion)> +<if(file.genPackage)> +namespace <file.genPackage> { +<endif> +<namedActions.header> +using System; +using Antlr4.Runtime; +using Antlr4.Runtime.Atn; +using Antlr4.Runtime.Misc; +using DFA = Antlr4.Runtime.Dfa.DFA; + +<lexer> +<if(file.genPackage)> +} // namespace <file.genPackage> +<endif> +>> + +Lexer(lexer, atn, actionFuncs, sempredFuncs, superClass) ::= << +[System.CodeDom.Compiler.GeneratedCode("ANTLR", "<file.ANTLRVersion>")] +[System.CLSCompliant(false)] +public partial class <csIdentifier.(lexer.name)> : <superClass; null="Lexer"> { + public const int + <lexer.tokens:{k | <tokenType.(k)>=<lexer.tokens.(k)>}; separator=", ", wrap, anchor>; + <if(lexer.channels)> + public const int + <lexer.channels:{k | <csIdentifier.(k)>=<lexer.channels.(k)>}; separator=", ", wrap, anchor>; + <endif> + <rest(lexer.modes):{m| public const int <modeName.(m)> = <i>;}; separator="\n"> + public static string[] modeNames = { + <lexer.modes:{m| "<m>"}; separator=", ", wrap, anchor> + }; + + public static readonly string[] ruleNames = { + <lexer.ruleNames:{r | "<r>"}; separator=", ", wrap, anchor> + }; + + <namedActions.members> + + public <csIdentifier.(lexer.name)>(ICharStream input) + : base(input) + { + Interpreter = new LexerATNSimulator(this,_ATN); + } + + <vocabulary(lexer.literalNames, lexer.symbolicNames)> + + public override string GrammarFileName { get { return "<lexer.grammarFileName>"; } } + + public override string[] RuleNames { get { return ruleNames; } } + + public override string[] ModeNames { get { return modeNames; } } + + public override string SerializedAtn { get { return _serializedATN; } } + + <dumpActions(lexer, "", actionFuncs, sempredFuncs)> + <atn> +} +>> + + +SerializedATN(model) ::= << +public static readonly string _serializedATN = + "<model.serialized; wrap={"+<\n><\t>"}>"; +public static readonly ATN _ATN = + new ATNDeserializer().Deserialize(_serializedATN.ToCharArray()); +>> + +initValue(typeName) ::= << +default(<typeName>) +>> + +codeFileExtension() ::= ".cs" + +modeName ::= [ + "DEFAULT_MODE" : "DefaultMode", + default : key +] + +channelName ::= [ + "HIDDEN" : "Hidden", + "DEFAULT_TOKEN_CHANNEL" : "DefaultTokenChannel", + default : key +] + +tokenType ::= [ + "EOF" : "Eof", + default : key +] + +csIdentifier ::= [ + "abstract" : "@abstract", + "as" : "@as", + "base" : "@base", + "bool" : "@bool", + "break" : "@break", + "byte" : "@byte", + "case" : "@case", + "catch" : "@catch", + "char" : "@char", + "checked" : "@checked", + "class" : "@class", + "const" : "@const", + "continue" : "@continue", + "decimal" : "@decimal", + "default" : "@default", + "delegate" : "@delegate", + "do" : "@do", + "double" : "@double", + "else" : "@else", + "enum" : "@enum", + "event" : "@event", + "explicit" : "@explicit", + "extern" : "@extern", + "false" : "@false", + "finally" : "@finally", + "fixed" : "@fixed", + "float" : "@float", + "for" : "@for", + "foreach" : "@foreach", + "goto" : "@goto", + "if" : "@if", + "implicit" : "@implicit", + "in" : "@in", + "int" : "@int", + "interface" : "@interface", + "internal" : "@internal", + "is" : "@is", + "lock" : "@lock", + "long" : "@long", + "namespace" : "@namespace", + "new" : "@new", + "null" : "@null", + "object" : "@object", + "operator" : "@operator", + "out" : "@out", + "override" : "@override", + "params" : "@params", + "private" : "@private", + "protected" : "@protected", + "public" : "@public", + "readonly" : "@readonly", + "ref" : "@ref", + "return" : "@return", + "sbyte" : "@sbyte", + "sealed" : "@sealed", + "short" : "@short", + "sizeof" : "@sizeof", + "stackalloc" : "@stackalloc", + "static" : "@static", + "string" : "@string", + "struct" : "@struct", + "switch" : "@switch", + "this" : "@this", + "throw" : "@throw", + "true" : "@true", + "try" : "@try", + "typeof" : "@typeof", + "uint" : "@uint", + "ulong" : "@ulong", + "unchecked" : "@unchecked", + "unsafe" : "@unsafe", + "ushort" : "@ushort", + "using" : "@using", + "virtual" : "@virtual", + "void" : "@void", + "volatile" : "@volatile", + "while" : "@while", + default : key +] diff --git a/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg b/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg new file mode 100644 index 0000000..5bec6c5 --- /dev/null +++ b/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg @@ -0,0 +1,975 @@ +/* + * [The "BSD license"] + * Copyright (c) 2012 Terence Parr + * Copyright (c) 2012 Sam Harwell + * 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. + */ + +javaTypeInitMap ::= [ + "int":"0", + "long":"0", + "float":"0.0f", + "double":"0.0", + "boolean":"false", + "byte":"0", + "short":"0", + "char":"0", + default:"null" // anything other than a primitive type is an object +] + +// args must be <object-model-object>, <fields-resulting-in-STs> + +ParserFile(file, parser, namedActions) ::= << +<fileHeader(file.grammarFileName, file.ANTLRVersion)> +<if(file.genPackage)> +package <file.genPackage>; +<endif> +<namedActions.header> +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.misc.*; +import org.antlr.v4.runtime.tree.*; +import java.util.List; +import java.util.Iterator; +import java.util.ArrayList; + +<parser> +>> + +ListenerFile(file, header) ::= << +<fileHeader(file.grammarFileName, file.ANTLRVersion)> +<if(file.genPackage)> +package <file.genPackage>; +<endif> +<header> +import org.antlr.v4.runtime.tree.ParseTreeListener; + +/** + * This interface defines a complete listener for a parse tree produced by + * {@link <file.parserName>}. + */ +public interface <file.grammarName>Listener extends ParseTreeListener { + <file.listenerNames:{lname | +/** +<if(file.listenerLabelRuleNames.(lname))> + * Enter a parse tree produced by the {@code <lname>\} + * labeled alternative in {@link <file.parserName>#<file.listenerLabelRuleNames.(lname)>\}. +<else> + * Enter a parse tree produced by {@link <file.parserName>#<lname>\}. +<endif> + * @param ctx the parse tree + */ +void enter<lname; format="cap">(<file.parserName>.<lname; format="cap">Context ctx); +/** +<if(file.listenerLabelRuleNames.(lname))> + * Exit a parse tree produced by the {@code <lname>\} + * labeled alternative in {@link <file.parserName>#<file.listenerLabelRuleNames.(lname)>\}. +<else> + * Exit a parse tree produced by {@link <file.parserName>#<lname>\}. +<endif> + * @param ctx the parse tree + */ +void exit<lname; format="cap">(<file.parserName>.<lname; format="cap">Context ctx);}; separator="\n"> +} +>> + +BaseListenerFile(file, header) ::= << +<fileHeader(file.grammarFileName, file.ANTLRVersion)> +<if(file.genPackage)> +package <file.genPackage>; +<endif> +<header> + +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.tree.ErrorNode; +import org.antlr.v4.runtime.tree.TerminalNode; + +/** + * This class provides an empty implementation of {@link <file.grammarName>Listener}, + * which can be extended to create a listener which only needs to handle a subset + * of the available methods. + */ +public class <file.grammarName>BaseListener implements <file.grammarName>Listener { + <file.listenerNames:{lname | +/** + * {@inheritDoc\} + * + * \<p>The default implementation does nothing.\</p> + */ +@Override public void enter<lname; format="cap">(<file.parserName>.<lname; format="cap">Context ctx) { \} +/** + * {@inheritDoc\} + * + * \<p>The default implementation does nothing.\</p> + */ +@Override public void exit<lname; format="cap">(<file.parserName>.<lname; format="cap">Context ctx) { \}}; separator="\n"> + + /** + * {@inheritDoc\} + * + * \<p>The default implementation does nothing.\</p> + */ + @Override public void enterEveryRule(ParserRuleContext ctx) { } + /** + * {@inheritDoc\} + * + * \<p>The default implementation does nothing.\</p> + */ + @Override public void exitEveryRule(ParserRuleContext ctx) { } + /** + * {@inheritDoc\} + * + * \<p>The default implementation does nothing.\</p> + */ + @Override public void visitTerminal(TerminalNode node) { } + /** + * {@inheritDoc\} + * + * \<p>The default implementation does nothing.\</p> + */ + @Override public void visitErrorNode(ErrorNode node) { } +} +>> + +VisitorFile(file, header) ::= << +<fileHeader(file.grammarFileName, file.ANTLRVersion)> +<if(file.genPackage)> +package <file.genPackage>; +<endif> +<header> +import org.antlr.v4.runtime.tree.ParseTreeVisitor; + +/** + * This interface defines a complete generic visitor for a parse tree produced + * by {@link <file.parserName>}. + * + * @param \<T> The return type of the visit operation. Use {@link Void} for + * operations with no return type. + */ +public interface <file.grammarName>Visitor\<T> extends ParseTreeVisitor\<T> { + <file.visitorNames:{lname | +/** +<if(file.visitorLabelRuleNames.(lname))> + * Visit a parse tree produced by the {@code <lname>\} + * labeled alternative in {@link <file.parserName>#<file.visitorLabelRuleNames.(lname)>\}. +<else> + * Visit a parse tree produced by {@link <file.parserName>#<lname>\}. +<endif> + * @param ctx the parse tree + * @return the visitor result + */ +T visit<lname; format="cap">(<file.parserName>.<lname; format="cap">Context ctx);}; separator="\n"> +} +>> + +BaseVisitorFile(file, header) ::= << +<fileHeader(file.grammarFileName, file.ANTLRVersion)> +<if(file.genPackage)> +package <file.genPackage>; +<endif> +<header> +import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor; + +/** + * This class provides an empty implementation of {@link <file.grammarName>Visitor}, + * which can be extended to create a visitor which only needs to handle a subset + * of the available methods. + * + * @param \<T> The return type of the visit operation. Use {@link Void} for + * operations with no return type. + */ +public class <file.grammarName>BaseVisitor\<T> extends AbstractParseTreeVisitor\<T> implements <file.grammarName>Visitor\<T> { + <file.visitorNames:{lname | +/** + * {@inheritDoc\} + * + * \<p>The default implementation returns the result of calling + * {@link #visitChildren\} on {@code ctx\}.\</p> + */ +@Override public T visit<lname; format="cap">(<file.parserName>.<lname; format="cap">Context ctx) { return visitChildren(ctx); \}}; separator="\n"> +} +>> + +fileHeader(grammarFileName, ANTLRVersion) ::= << +// Generated from <grammarFileName; format="java-escape"> by ANTLR <ANTLRVersion> +>> + +Parser(parser, funcs, atn, sempredFuncs, superClass) ::= << +<Parser_(ctor="parser_ctor", ...)> +>> + +Parser_(parser, funcs, atn, sempredFuncs, ctor, superClass) ::= << +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) +public class <parser.name> extends <superClass; null="Parser"> { + static { RuntimeMetaData.checkVersion("<file.ANTLRVersion>", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + <if(parser.tokens)> + public static final int + <parser.tokens:{k | <k>=<parser.tokens.(k)>}; separator=", ", wrap, anchor>; + <endif> + public static final int + <parser.rules:{r | RULE_<r.name> = <r.index>}; separator=", ", wrap, anchor>; + public static final String[] ruleNames = { + <parser.ruleNames:{r | "<r>"}; separator=", ", wrap, anchor> + }; + + <vocabulary(parser.literalNames, parser.symbolicNames)> + + @Override + public String getGrammarFileName() { return "<parser.grammarFileName; format="java-escape">"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public ATN getATN() { return _ATN; } + + <namedActions.members> + <parser:(ctor)()> + <funcs; separator="\n"> + +<if(sempredFuncs)> + public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) { + switch (ruleIndex) { + <parser.sempredFuncs.values:{f| +case <f.ruleIndex>: + return <f.name>_sempred((<f.ctxType>)_localctx, predIndex);}; separator="\n"> + } + return true; + } + <sempredFuncs.values; separator="\n"> +<endif> + + <atn> +} +>> + +vocabulary(literalNames, symbolicNames) ::= << +private static final String[] _LITERAL_NAMES = { + <literalNames:{t | <t>}; null="null", separator=", ", wrap, anchor> +}; +private static final String[] _SYMBOLIC_NAMES = { + <symbolicNames:{t | <t>}; null="null", separator=", ", wrap, anchor> +}; +public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + +/** + * @deprecated Use {@link #VOCABULARY} instead. + */ +@Deprecated +public static final String[] tokenNames; +static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i \< tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = "\<INVALID>"; + } + } +} + +@Override +@Deprecated +public String[] getTokenNames() { + return tokenNames; +} + +@Override + +public Vocabulary getVocabulary() { + return VOCABULARY; +} +>> + +dumpActions(recog, argFuncs, actionFuncs, sempredFuncs) ::= << +<if(actionFuncs)> +@Override +public void action(RuleContext _localctx, int ruleIndex, int actionIndex) { + switch (ruleIndex) { + <recog.actionFuncs.values:{f| +case <f.ruleIndex>: + <f.name>_action((<f.ctxType>)_localctx, actionIndex); + break;}; separator="\n"> + } +} +<actionFuncs.values; separator="\n"> +<endif> +<if(sempredFuncs)> +@Override +public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) { + switch (ruleIndex) { + <recog.sempredFuncs.values:{f| +case <f.ruleIndex>: + return <f.name>_sempred((<f.ctxType>)_localctx, predIndex);}; separator="\n"> + } + return true; +} +<sempredFuncs.values; separator="\n"> +<endif> +>> + +parser_ctor(p) ::= << +public <p.name>(TokenStream input) { + super(input); + _interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); +} +>> + +/* This generates a private method since the actionIndex is generated, making an + * overriding implementation impossible to maintain. + */ +RuleActionFunction(r, actions) ::= << +private void <r.name>_action(<r.ctxType> _localctx, int actionIndex) { + switch (actionIndex) { + <actions:{index| +case <index>: + <actions.(index)> + break;}; separator="\n"> + } +} +>> + +/* This generates a private method since the predIndex is generated, making an + * overriding implementation impossible to maintain. + */ +RuleSempredFunction(r, actions) ::= << +private boolean <r.name>_sempred(<r.ctxType> _localctx, int predIndex) { + switch (predIndex) { + <actions:{index| +case <index>: + return <actions.(index)>;}; separator="\n"> + } + return true; +} +>> + +RuleFunction(currentRule,args,code,locals,ruleCtx,altLabelCtxs,namedActions,finallyAction,postamble,exceptions) ::= << + +<ruleCtx> +<altLabelCtxs:{l | <altLabelCtxs.(l)>}; separator="\n"> + +<if(currentRule.modifiers)><currentRule.modifiers:{f | <f> }><else>public final <endif><currentRule.ctxType> <currentRule.name>(<args; separator=",">) throws RecognitionException { + <currentRule.ctxType> _localctx = new <currentRule.ctxType>(_ctx, getState()<currentRule.args:{a | , <a.name>}>); + enterRule(_localctx, <currentRule.startState>, RULE_<currentRule.name>); + <namedActions.init> + <locals; separator="\n"> + try { +<if(currentRule.hasLookaheadBlock)> + int _alt; +<endif> + <code> + <postamble; separator="\n"> + <namedActions.after> + } + <if(exceptions)> + <exceptions; separator="\n"> + <else> + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + <endif> + finally { + <finallyAction> + exitRule(); + } + return _localctx; +} +>> + +LeftRecursiveRuleFunction(currentRule,args,code,locals,ruleCtx,altLabelCtxs, + namedActions,finallyAction,postamble) ::= +<< + +<ruleCtx> +<altLabelCtxs:{l | <altLabelCtxs.(l)>}; separator="\n"> + +<if(currentRule.modifiers)><currentRule.modifiers:{f | <f> }><else>public final <endif><currentRule.ctxType> <currentRule.name>(<args; separator=", ">) throws RecognitionException { + return <currentRule.name>(0<currentRule.args:{a | , <a.name>}>); +} + +private <currentRule.ctxType> <currentRule.name>(int _p<args:{a | , <a>}>) throws RecognitionException { + ParserRuleContext _parentctx = _ctx; + int _parentState = getState(); + <currentRule.ctxType> _localctx = new <currentRule.ctxType>(_ctx, _parentState<currentRule.args:{a | , <a.name>}>); + <currentRule.ctxType> _prevctx = _localctx; + int _startState = <currentRule.startState>; + enterRecursionRule(_localctx, <currentRule.startState>, RULE_<currentRule.name>, _p); + <namedActions.init> + <locals; separator="\n"> + try { +<if(currentRule.hasLookaheadBlock)> + int _alt; +<endif> + <code> + <postamble; separator="\n"> + <namedActions.after> + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + <finallyAction> + unrollRecursionContexts(_parentctx); + } + return _localctx; +} +>> + +CodeBlockForOuterMostAlt(currentOuterMostAltCodeBlock, locals, preamble, ops) ::= << +<if(currentOuterMostAltCodeBlock.altLabel)>_localctx = new <currentOuterMostAltCodeBlock.altLabel; format="cap">Context(_localctx);<endif> +enterOuterAlt(_localctx, <currentOuterMostAltCodeBlock.alt.altNum>); +<CodeBlockForAlt(currentAltCodeBlock=currentOuterMostAltCodeBlock, ...)> +>> + +CodeBlockForAlt(currentAltCodeBlock, locals, preamble, ops) ::= << +{ +<locals; separator="\n"> +<preamble; separator="\n"> +<ops; separator="\n"> +} +>> + +LL1AltBlock(choice, preamble, alts, error) ::= << +setState(<choice.stateNumber>); +<!_errHandler.sync(this);!> +<if(choice.label)><labelref(choice.label)> = _input.LT(1);<endif> +<preamble; separator="\n"> +switch (_input.LA(1)) { +<choice.altLook,alts:{look,alt| <cases(ttypes=look)> + <alt> + break;}; separator="\n"> +default: + <error> +} +>> + +LL1OptionalBlock(choice, alts, error) ::= << +setState(<choice.stateNumber>); +<!_errHandler.sync(this);!> +switch (_input.LA(1)) { +<choice.altLook,alts:{look,alt| <cases(ttypes=look)> + <alt> + break;}; separator="\n"> +default: + <error> +} +>> + +LL1OptionalBlockSingleAlt(choice, expr, alts, preamble, error, followExpr) ::= << +setState(<choice.stateNumber>); +<!_errHandler.sync(this);!> +<preamble; separator="\n"> +if (<expr>) { + <alts; separator="\n"> +} +<!else if ( !(<followExpr>) ) <error>!> +>> + +LL1StarBlockSingleAlt(choice, loopExpr, alts, preamble, iteration) ::= << +setState(<choice.stateNumber>); +_errHandler.sync(this); +<preamble; separator="\n"> +while (<loopExpr>) { + <alts; separator="\n"> + setState(<choice.loopBackStateNumber>); + _errHandler.sync(this); + <iteration> +} +>> + +LL1PlusBlockSingleAlt(choice, loopExpr, alts, preamble, iteration) ::= << +setState(<choice.blockStartStateNumber>); <! alt block decision !> +_errHandler.sync(this); +<preamble; separator="\n"> +do { + <alts; separator="\n"> + setState(<choice.stateNumber>); <! loopback/exit decision !> + _errHandler.sync(this); + <iteration> +} while ( <loopExpr> ); +>> + +// LL(*) stuff + +AltBlock(choice, preamble, alts, error) ::= << +setState(<choice.stateNumber>); +<!_errHandler.sync(this);!> +<if(choice.label)><labelref(choice.label)> = _input.LT(1);<endif> +<preamble; separator="\n"> +switch ( getInterpreter().adaptivePredict(_input,<choice.decision>,_ctx) ) { +<alts:{alt | +case <i>: + <alt> + break;}; separator="\n"> +} +>> + +OptionalBlock(choice, alts, error) ::= << +setState(<choice.stateNumber>); +<!_errHandler.sync(this);!> +switch ( getInterpreter().adaptivePredict(_input,<choice.decision>,_ctx) ) { +<alts:{alt | +case <i><if(!choice.ast.greedy)>+1<endif>: + <alt> + break;}; separator="\n"> +} +>> + +StarBlock(choice, alts, sync, iteration) ::= << +setState(<choice.stateNumber>); +_errHandler.sync(this); +_alt = getInterpreter().adaptivePredict(_input,<choice.decision>,_ctx); +while ( _alt!=<choice.exitAlt> && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1<if(!choice.ast.greedy)>+1<endif> ) { + <iteration> + <alts> <! should only be one !> + } + setState(<choice.loopBackStateNumber>); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,<choice.decision>,_ctx); +} +>> + +PlusBlock(choice, alts, error) ::= << +setState(<choice.blockStartStateNumber>); <! alt block decision !> +_errHandler.sync(this); +_alt = 1<if(!choice.ast.greedy)>+1<endif>; +do { + switch (_alt) { + <alts:{alt| +case <i><if(!choice.ast.greedy)>+1<endif>: + <alt> + break;}; separator="\n"> + default: + <error> + } + setState(<choice.loopBackStateNumber>); <! loopback/exit decision !> + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,<choice.decision>,_ctx); +} while ( _alt!=<choice.exitAlt> && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ); +>> + +Sync(s) ::= "sync(<s.expecting.name>);" + +ThrowNoViableAlt(t) ::= "throw new NoViableAltException(this);" + +TestSetInline(s) ::= << +<s.bitsets:{bits | <if(rest(rest(bits.ttypes)))><bitsetBitfieldComparison(s, bits)><else><bitsetInlineComparison(s, bits)><endif>}; separator=" || "> +>> + +// Java language spec 15.19 - shift operators mask operands rather than overflow to 0... need range test +testShiftInRange(shiftAmount) ::= << +((<shiftAmount>) & ~0x3f) == 0 +>> + +// produces smaller bytecode only when bits.ttypes contains more than two items +bitsetBitfieldComparison(s, bits) ::= <% +(<testShiftInRange({<offsetShift(s.varName, bits.shift)>})> && ((1L \<\< <offsetShift(s.varName, bits.shift)>) & (<bits.ttypes:{ttype | (1L \<\< <offsetShift(ttype, bits.shift)>)}; separator=" | ">)) != 0) +%> + +isZero ::= [ +"0":true, +default:false +] + +offsetShift(shiftAmount, offset) ::= <% +<if(!isZero.(offset))>(<shiftAmount> - <offset>)<else><shiftAmount><endif> +%> + +// produces more efficient bytecode when bits.ttypes contains at most two items +bitsetInlineComparison(s, bits) ::= <% +<bits.ttypes:{ttype | <s.varName>==<ttype>}; separator=" || "> +%> + +cases(ttypes) ::= << +<ttypes:{t | case <t>:}; separator="\n"> +>> + +InvokeRule(r, argExprsChunks) ::= << +setState(<r.stateNumber>); +<if(r.labels)><r.labels:{l | <labelref(l)> = }><endif><r.name>(<if(r.ast.options.p)><r.ast.options.p><if(argExprsChunks)>,<endif><endif><argExprsChunks>); +>> + +MatchToken(m) ::= << +setState(<m.stateNumber>); +<if(m.labels)><m.labels:{l | <labelref(l)> = }><endif>match(<m.name>); +>> + +MatchSet(m, expr, capture) ::= "<CommonSetStuff(m, expr, capture, false)>" + +MatchNotSet(m, expr, capture) ::= "<CommonSetStuff(m, expr, capture, true)>" + +CommonSetStuff(m, expr, capture, invert) ::= << +setState(<m.stateNumber>); +<if(m.labels)><m.labels:{l | <labelref(l)> = }>_input.LT(1);<endif> +<capture> +if ( <if(invert)><m.varName> \<= 0 || <else>!<endif>(<expr>) ) { + <if(m.labels)><m.labels:{l | <labelref(l)> = (Token)}><endif>_errHandler.recoverInline(this); +} else { + consume(); +} +>> + +Wildcard(w) ::= << +setState(<w.stateNumber>); +<if(w.labels)><w.labels:{l | <labelref(l)> = }><endif>matchWildcard(); +>> + +// ACTION STUFF + +Action(a, foo, chunks) ::= "<chunks>" + +ArgAction(a, chunks) ::= "<chunks>" + +SemPred(p, chunks, failChunks) ::= << +setState(<p.stateNumber>); +if (!(<chunks>)) throw new FailedPredicateException(this, <p.predicate><if(failChunks)>, <failChunks><elseif(p.msg)>, <p.msg><endif>); +>> + +ExceptionClause(e, catchArg, catchAction) ::= << +catch (<catchArg>) { + <catchAction> +} +>> + +// lexer actions are not associated with model objects + +LexerSkipCommand() ::= "skip();" +LexerMoreCommand() ::= "more();" +LexerPopModeCommand() ::= "popMode();" + +LexerTypeCommand(arg) ::= "_type = <arg>;" +LexerChannelCommand(arg) ::= "_channel = <arg>;" +LexerModeCommand(arg) ::= "_mode = <arg>;" +LexerPushModeCommand(arg) ::= "pushMode(<arg>);" + +ActionText(t) ::= "<t.text>" +ActionTemplate(t) ::= "<t.st>" +ArgRef(a) ::= "_localctx.<a.name>" +LocalRef(a) ::= "_localctx.<a.name>" +RetValueRef(a) ::= "_localctx.<a.name>" +QRetValueRef(a) ::= "<ctx(a)>.<a.dict>.<a.name>" +/** How to translate $tokenLabel */ +TokenRef(t) ::= "<ctx(t)>.<t.name>" +LabelRef(t) ::= "<ctx(t)>.<t.name>" +ListLabelRef(t) ::= "<ctx(t)>.<ListLabelName(t.name)>" +SetAttr(s,rhsChunks) ::= "<ctx(s)>.<s.name> = <rhsChunks>;" + +TokenLabelType() ::= "<file.TokenLabelType; null={Token}>" +InputSymbolType() ::= "<file.InputSymbolType; null={Token}>" + +TokenPropertyRef_text(t) ::= "(<ctx(t)>.<t.label>!=null?<ctx(t)>.<t.label>.getText():null)" +TokenPropertyRef_type(t) ::= "(<ctx(t)>.<t.label>!=null?<ctx(t)>.<t.label>.getType():0)" +TokenPropertyRef_line(t) ::= "(<ctx(t)>.<t.label>!=null?<ctx(t)>.<t.label>.getLine():0)" +TokenPropertyRef_pos(t) ::= "(<ctx(t)>.<t.label>!=null?<ctx(t)>.<t.label>.getCharPositionInLine():0)" +TokenPropertyRef_channel(t) ::= "(<ctx(t)>.<t.label>!=null?<ctx(t)>.<t.label>.getChannel():0)" +TokenPropertyRef_index(t) ::= "(<ctx(t)>.<t.label>!=null?<ctx(t)>.<t.label>.getTokenIndex():0)" +TokenPropertyRef_int(t) ::= "(<ctx(t)>.<t.label>!=null?Integer.valueOf(<ctx(t)>.<t.label>.getText()):0)" + +RulePropertyRef_start(r) ::= "(<ctx(r)>.<r.label>!=null?(<ctx(r)>.<r.label>.start):null)" +RulePropertyRef_stop(r) ::= "(<ctx(r)>.<r.label>!=null?(<ctx(r)>.<r.label>.stop):null)" +RulePropertyRef_text(r) ::= "(<ctx(r)>.<r.label>!=null?_input.getText(<ctx(r)>.<r.label>.start,<ctx(r)>.<r.label>.stop):null)" +RulePropertyRef_ctx(r) ::= "<ctx(r)>.<r.label>" +RulePropertyRef_parser(r) ::= "this" + +ThisRulePropertyRef_start(r) ::= "_localctx.start" +ThisRulePropertyRef_stop(r) ::= "_localctx.stop" +ThisRulePropertyRef_text(r) ::= "_input.getText(_localctx.start, _input.LT(-1))" +ThisRulePropertyRef_ctx(r) ::= "_localctx" +ThisRulePropertyRef_parser(r) ::= "this" + +NonLocalAttrRef(s) ::= "((<s.ruleName; format=\"cap\">Context)getInvokingContext(<s.ruleIndex>)).<s.name>" +SetNonLocalAttr(s, rhsChunks) ::= + "((<s.ruleName; format=\"cap\">Context)getInvokingContext(<s.ruleIndex>)).<s.name> = <rhsChunks>;" + +AddToLabelList(a) ::= "<ctx(a.label)>.<a.listName>.add(<labelref(a.label)>);" + +TokenDecl(t) ::= "<TokenLabelType()> <t.name>" +TokenTypeDecl(t) ::= "int <t.name>;" +TokenListDecl(t) ::= "List\<Token> <t.name> = new ArrayList\<Token>()" +RuleContextDecl(r) ::= "<r.ctxName> <r.name>" +RuleContextListDecl(rdecl) ::= "List\<<rdecl.ctxName>> <rdecl.name> = new ArrayList\<<rdecl.ctxName>>()" + +ContextTokenGetterDecl(t) ::= + "public TerminalNode <t.name>() { return getToken(<parser.name>.<t.name>, 0); }" +ContextTokenListGetterDecl(t) ::= + "public List\<TerminalNode> <t.name>() { return getTokens(<parser.name>.<t.name>); }" +ContextTokenListIndexedGetterDecl(t) ::= << +public TerminalNode <t.name>(int i) { + return getToken(<parser.name>.<t.name>, i); +} +>> +ContextRuleGetterDecl(r) ::= << +public <r.ctxName> <r.name>() { + return getRuleContext(<r.ctxName>.class,0); +} +>> +ContextRuleListGetterDecl(r) ::= << +public List\<<r.ctxName>\> <r.name>() { + return getRuleContexts(<r.ctxName>.class); +} +>> +ContextRuleListIndexedGetterDecl(r) ::= << +public <r.ctxName> <r.name>(int i) { + return getRuleContext(<r.ctxName>.class,i); +} +>> + +LexerRuleContext() ::= "RuleContext" + +/** The rule context name is the rule followed by a suffix; e.g., + * r becomes rContext. + */ +RuleContextNameSuffix() ::= "Context" + +ImplicitTokenLabel(tokenName) ::= "<tokenName>" +ImplicitRuleLabel(ruleName) ::= "<ruleName>" +ImplicitSetLabel(id) ::= "_tset<id>" +ListLabelName(label) ::= "<label>" + +CaptureNextToken(d) ::= "<d.varName> = _input.LT(1);" +CaptureNextTokenType(d) ::= "<d.varName> = _input.LA(1);" + +StructDecl(struct,ctorAttrs,attrs,getters,dispatchMethods,interfaces,extensionMembers, + superClass={ParserRuleContext}) ::= << +public static class <struct.name> extends <superClass><if(interfaces)> implements <interfaces; separator=", "><endif> { + <attrs:{a | public <a>;}; separator="\n"> + <getters:{g | <g>}; separator="\n"> + <if(ctorAttrs)>public <struct.name>(ParserRuleContext parent, int invokingState) { super(parent, invokingState); }<endif> + public <struct.name>(ParserRuleContext parent, int invokingState<ctorAttrs:{a | , <a>}>) { + super(parent, invokingState); + <struct.ctorAttrs:{a | this.<a.name> = <a.name>;}; separator="\n"> + } + @Override public int getRuleIndex() { return RULE_<struct.derivedFromName>; } +<if(struct.provideCopyFrom)> <! don't need copy unless we have subclasses !> + public <struct.name>() { } + public void copyFrom(<struct.name> ctx) { + super.copyFrom(ctx); + <struct.attrs:{a | this.<a.name> = ctx.<a.name>;}; separator="\n"> + } +<endif> + <dispatchMethods; separator="\n"> + <extensionMembers; separator="\n"> +} +>> + +AltLabelStructDecl(struct,attrs,getters,dispatchMethods) ::= << +public static class <struct.name> extends <currentRule.name; format="cap">Context { + <attrs:{a | public <a>;}; separator="\n"> + <getters:{g | <g>}; separator="\n"> + public <struct.name>(<currentRule.name; format="cap">Context ctx) { copyFrom(ctx); } + <dispatchMethods; separator="\n"> +} +>> + +ListenerDispatchMethod(method) ::= << +@Override +public void <if(method.isEnter)>enter<else>exit<endif>Rule(ParseTreeListener listener) { + if ( listener instanceof <parser.grammarName>Listener ) ((<parser.grammarName>Listener)listener).<if(method.isEnter)>enter<else>exit<endif><struct.derivedFromName; format="cap">(this); +} +>> + +VisitorDispatchMethod(method) ::= << +@Override +public \<T> T accept(ParseTreeVisitor\<? extends T> visitor) { + if ( visitor instanceof <parser.grammarName>Visitor ) return ((<parser.grammarName>Visitor\<? extends T>)visitor).visit<struct.derivedFromName; format="cap">(this); + else return visitor.visitChildren(this); +} +>> + +AttributeDecl(d) ::= "<d.type> <d.name><if(d.initValue)> = <d.initValue><endif>" + +/** If we don't know location of label def x, use this template */ +labelref(x) ::= "<if(!x.isLocal)>((<x.ctx.name>)_localctx).<endif><x.name>" + +/** For any action chunk, what is correctly-typed context struct ptr? */ +ctx(actionChunk) ::= "((<actionChunk.ctx.name>)_localctx)" + +// used for left-recursive rules +recRuleAltPredicate(ruleName,opPrec) ::= "precpred(_ctx, <opPrec>)" +recRuleSetReturnAction(src,name) ::= "$<name>=$<src>.<name>;" +recRuleSetStopToken() ::= "_ctx.stop = _input.LT(-1);" + +recRuleAltStartAction(ruleName, ctxName, label, isListLabel) ::= << +_localctx = new <ctxName>Context(_parentctx, _parentState); +<if(label)> +<if(isListLabel)> +_localctx.<label>.add(_prevctx); +<else> +_localctx.<label> = _prevctx; +<endif> +<endif> +<if(label)>_localctx.<label> = _prevctx;<endif> +pushNewRecursionContext(_localctx, _startState, RULE_<ruleName>); +>> + +recRuleLabeledAltStartAction(ruleName, currentAltLabel, label, isListLabel) ::= << +_localctx = new <currentAltLabel; format="cap">Context(new <ruleName; format="cap">Context(_parentctx, _parentState)); +<if(label)> +<if(isListLabel)> +((<currentAltLabel; format="cap">Context)_localctx).<label>.add(_prevctx); +<else> +((<currentAltLabel; format="cap">Context)_localctx).<label> = _prevctx; +<endif> +<endif> +pushNewRecursionContext(_localctx, _startState, RULE_<ruleName>); +>> + +recRuleReplaceContext(ctxName) ::= << +_localctx = new <ctxName>Context(_localctx); +_ctx = _localctx; +_prevctx = _localctx; +>> + +recRuleSetPrevCtx() ::= << +if ( _parseListeners!=null ) triggerExitRuleEvent(); +_prevctx = _localctx; +>> + + +LexerFile(lexerFile, lexer, namedActions) ::= << +<fileHeader(lexerFile.grammarFileName, lexerFile.ANTLRVersion)> +<if(lexerFile.genPackage)> +package <lexerFile.genPackage>; +<endif> +<namedActions.header> +import org.antlr.v4.runtime.Lexer; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.TokenStream; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.misc.*; + +<lexer> +>> + +Lexer(lexer, atn, actionFuncs, sempredFuncs, superClass) ::= << +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) +public class <lexer.name> extends <superClass; null="Lexer"> { + static { RuntimeMetaData.checkVersion("<lexerFile.ANTLRVersion>", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + <lexer.tokens:{k | <k>=<lexer.tokens.(k)>}; separator=", ", wrap, anchor>; + <if(lexer.channels)> + public static final int + <lexer.channels:{k | <k>=<lexer.channels.(k)>}; separator=", ", wrap, anchor>; + <endif> + <rest(lexer.modes):{m| public static final int <m> = <i>;}; separator="\n"> + public static String[] modeNames = { + <lexer.modes:{m| "<m>"}; separator=", ", wrap, anchor> + }; + + public static final String[] ruleNames = { + <lexer.ruleNames:{r | "<r>"}; separator=", ", wrap, anchor> + }; + + <vocabulary(lexer.literalNames, lexer.symbolicNames)> + + <namedActions.members> + + public <lexer.name>(CharStream input) { + super(input); + _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @Override + public String getGrammarFileName() { return "<lexer.grammarFileName>"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public String[] getModeNames() { return modeNames; } + + @Override + public ATN getATN() { return _ATN; } + + <dumpActions(lexer, "", actionFuncs, sempredFuncs)> + <atn> +} +>> + +SerializedATN(model) ::= << +<if(rest(model.segments))> +<! requires segmented representation !> +private static final int _serializedATNSegments = <length(model.segments)>; +<model.segments:{segment|private static final String _serializedATNSegment<i0> = + "<segment; wrap={"+<\n><\t>"}>";}; separator="\n"> +public static final String _serializedATN = Utils.join( + new String[] { + <model.segments:{segment | _serializedATNSegment<i0>}; separator=",\n"> + }, + "" +); +<else> +<! only one segment, can be inlined !> +public static final String _serializedATN = + "<model.serialized; wrap={"+<\n><\t>"}>"; +<endif> +public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); +static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i \< _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } +<! org.antlr.v4.tool.DOTGenerator dot = new org.antlr.v4.tool.DOTGenerator(null);!> +<! System.out.println(dot.getDOT(_ATN.decisionToState.get(0), ruleNames, false));!> +<! System.out.println(dot.getDOT(_ATN.ruleToStartState[2], ruleNames, false));!> +} +>> + +/** 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) ::= << +<javaTypeInitMap.(typeName)> +>> + +codeFileExtension() ::= ".java" diff --git a/tool/resources/org/antlr/v4/tool/templates/codegen/JavaScript/JavaScript.stg b/tool/resources/org/antlr/v4/tool/templates/codegen/JavaScript/JavaScript.stg new file mode 100644 index 0000000..a9cfef1 --- /dev/null +++ b/tool/resources/org/antlr/v4/tool/templates/codegen/JavaScript/JavaScript.stg @@ -0,0 +1,858 @@ +/* + * [The "BSD license"] + * Copyright (c) 2012 Terence Parr + * Copyright (c) 2012 Sam Harwell + * Copyright (c) 2014 Eric Vergnaud + * 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. + */ + +/** ANTLR tool checks output templates are compatible with tool code generation. + * For now, a simple string match used on x.y of x.y.z scheme. + * Must match Tool.VERSION during load to templates. + * + * REQUIRED. + */ + +pythonTypeInitMap ::= [ + "bool":"False", + "int":"0", + "float":"0.0", + "str":"", + default:"None" // anything other than a primitive type is an object +] + +// args must be <object-model-object>, <fields-resulting-in-STs> + +ParserFile(file, parser, namedActions) ::= << +<fileHeader(file.grammarFileName, file.ANTLRVersion)> +var antlr4 = require('antlr4/index'); +<if(file.genListener)> +var <file.grammarName>Listener = require('./<file.grammarName>Listener').<file.grammarName>Listener; +<endif> +<if(file.genVisitor)> +var <file.grammarName>Visitor = require('./<file.grammarName>Visitor').<file.grammarName>Visitor; +<endif> + +<namedActions.header> +<parser> +>> + +ListenerFile(file, header) ::= << +<fileHeader(file.grammarFileName, file.ANTLRVersion)> +var antlr4 = require('antlr4/index'); + +// This class defines a complete listener for a parse tree produced by <file.parserName>. +function <file.grammarName>Listener() { + antlr4.tree.ParseTreeListener.call(this); + return this; +} + +<file.grammarName>Listener.prototype = Object.create(antlr4.tree.ParseTreeListener.prototype); +<file.grammarName>Listener.prototype.constructor = <file.grammarName>Listener; + +<file.listenerNames:{lname | +// Enter a parse tree produced by <file.parserName>#<lname>. +<file.grammarName>Listener.prototype.enter<lname; format="cap"> = function(ctx) { +\}; + +// Exit a parse tree produced by <file.parserName>#<lname>. +<file.grammarName>Listener.prototype.exit<lname; format="cap"> = function(ctx) { +\}; + +}; separator="\n"> + +exports.<file.grammarName>Listener = <file.grammarName>Listener; +>> + + +VisitorFile(file, header) ::= << +<fileHeader(file.grammarFileName, file.ANTLRVersion)> +var antlr4 = require('antlr4/index'); +<header> + +// This class defines a complete generic visitor for a parse tree produced by <file.parserName>. + +function <file.grammarName>Visitor() { + antlr4.tree.ParseTreeVisitor.call(this); + return this; +} + +<file.grammarName>Visitor.prototype = Object.create(antlr4.tree.ParseTreeVisitor.prototype); +<file.grammarName>Visitor.prototype.constructor = <file.grammarName>Visitor; + +<file.visitorNames:{lname | +// Visit a parse tree produced by <file.parserName>#<lname>. +<file.grammarName>Visitor.prototype.visit<lname; format="cap"> = function(ctx) { +\}; + +}; separator="\n"> + +exports.<file.grammarName>Visitor = <file.grammarName>Visitor; +>> + + +fileHeader(grammarFileName, ANTLRVersion) ::= << +// Generated from <grammarFileName; format="java-escape"> by ANTLR <ANTLRVersion> +// jshint ignore: start +>> + +Parser(parser, funcs, atn, sempredFuncs, superClass) ::= << +<if(superClass)> +var <superClass> = require('./<superClass>').<superClass>; +<endif> + +var grammarFileName = "<parser.grammarFileName; format="java-escape">"; + +<atn> + +var atn = new antlr4.atn.ATNDeserializer().deserialize(serializedATN); + +var decisionsToDFA = atn.decisionToState.map( function(ds, index) { return new antlr4.dfa.DFA(ds, index); }); + +var sharedContextCache = new antlr4.PredictionContextCache(); + +var literalNames = [ <parser.literalNames:{t | <t>}; null="'null'", separator=", ", wrap, anchor> ]; + +var symbolicNames = [ <parser.symbolicNames:{t | <t>}; null="'null'", separator=", ", wrap, anchor> ]; + +var ruleNames = [ <parser.ruleNames:{r | "<r>"}; separator=", ", wrap, anchor> ]; + +function <parser.name> (input) { + <superClass; null="antlr4.Parser">.call(this, input); + this._interp = new antlr4.atn.ParserATNSimulator(this, atn, decisionsToDFA, sharedContextCache); + this.ruleNames = ruleNames; + this.literalNames = literalNames; + this.symbolicNames = symbolicNames; + <namedActions.members> + return this; +} + +<parser.name>.prototype = Object.create(<superClass; null="antlr4.Parser">.prototype); +<parser.name>.prototype.constructor = <parser.name>; + +Object.defineProperty(<parser.name>.prototype, "atn", { + get : function() { + return atn; + } +}); + +<parser.name>.EOF = antlr4.Token.EOF; +<if(parser.tokens)> +<parser.tokens:{k | <parser.name>.<k> = <parser.tokens.(k)>;}; separator="\n", wrap, anchor> +<endif> + +<parser.rules:{r | <parser.name>.RULE_<r.name> = <r.index>;}; separator="\n", wrap, anchor> + +<funcs; separator="\n"> + +<if(sempredFuncs)> +<parser.name>.prototype.sempred = function(localctx, ruleIndex, predIndex) { + switch(ruleIndex) { + <parser.sempredFuncs.values:{f | case <f.ruleIndex>: + return this.<f.name>_sempred(localctx, predIndex);}; separator="\n"> + default: + throw "No predicate with index:" + ruleIndex; + } +}; + +<sempredFuncs.values; separator="\n"> +<endif> + +exports.<parser.name> = <parser.name>; + +>> + +dumpActions(recog, argFuncs, actionFuncs, sempredFuncs) ::= << +<if(actionFuncs)> +<lexer.name>.prototype.action = function(localctx, ruleIndex, actionIndex) { + switch (ruleIndex) { + <recog.actionFuncs.values:{f| +case <f.ruleIndex>: + this.<f.name>_action(localctx, actionIndex); + break;}; separator="\n"> + default: + throw "No registered action for:" + ruleIndex; + } +}; + +<actionFuncs.values; separator="\n"> +<endif> +<if(sempredFuncs)> +<lexer.name>.prototype.sempred = function(localctx, ruleIndex, predIndex) { + switch (ruleIndex) { + <recog.sempredFuncs.values:{f| case <f.ruleIndex>: + return this.<f.name>_sempred(localctx, predIndex);}; separator="\n"> + default: + throw "No registered predicate for:" + ruleIndex; + } +}; + +<sempredFuncs.values; separator="\n"> +<endif> +>> + + +/* This generates a private method since the actionIndex is generated, making an + * overriding implementation impossible to maintain. + */ +RuleActionFunction(r, actions) ::= << + +<lexer.name>.prototype.<r.name>_action = function(localctx , actionIndex) { + switch (actionIndex) { + <actions:{index| +case <index>: + <actions.(index)> + break;}; separator="\n"> + default: + throw "No registered action for:" + actionIndex; + } +}; +>> + +/* This generates a private method since the predIndex is generated, making an + * overriding implementation impossible to maintain. + */ +RuleSempredFunction(r, actions) ::= << +<if(parser)><parser.name><else><lexer.name><endif>.prototype.<r.name>_sempred = function(localctx, predIndex) { + switch(predIndex) { + <actions:{index| case <index>: + return <actions.(index)>;}; separator="\n"> + default: + throw "No predicate with index:" + predIndex; + } +}; + +>> + +RuleFunction(currentRule,args,code,locals,ruleCtx,altLabelCtxs,namedActions,finallyAction,postamble,exceptions) ::= << + +<ruleCtx> + +<altLabelCtxs:{l | <altLabelCtxs.(l)>}; separator="\n"> + +<! Define fields of this parser to export the context classes !> +<parser.name>.<currentRule.ctxType> = <currentRule.ctxType>; + +<parser.name>.prototype.<currentRule.name> = function(<currentRule.args:{a | <a.name>}; separator=", ">) { + + var localctx = new <currentRule.ctxType>(this, this._ctx, this.state<currentRule.args:{a | , <a.name>}>); + this.enterRule(localctx, <currentRule.startState>, <parser.name>.RULE_<currentRule.name>); + <namedActions.init> + <locals; separator="\n"> + try { + <code> + <postamble; separator="\n"> + <namedActions.after> + <if(exceptions)> + <exceptions; separator="\n"> + <else> + } catch (re) { + if(re instanceof antlr4.error.RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + }<endif> finally { + <finallyAction> + this.exitRule(); + } + return localctx; +}; + +>> + +LeftRecursiveRuleFunction(currentRule,args,code,locals,ruleCtx,altLabelCtxs, + namedActions,finallyAction,postamble) ::= +<< + +<ruleCtx> +<altLabelCtxs:{l | <altLabelCtxs.(l)>}; separator="\n"> + +<parser.name>.prototype.<currentRule.name> = function(_p<if(currentRule.args)>, <args:{a | , <a>}><endif>) { + if(_p===undefined) { + _p = 0; + } + var _parentctx = this._ctx; + var _parentState = this.state; + var localctx = new <currentRule.ctxType>(this, this._ctx, _parentState<args:{a | , <a.name>}>); + var _prevctx = localctx; + var _startState = <currentRule.startState>; + this.enterRecursionRule(localctx, <currentRule.startState>, <parser.name>.RULE_<currentRule.name>, _p); + <namedActions.init> + <locals; separator="\n"> + try { + <code> + <postamble; separator="\n"> + <namedActions.after> + } catch( error) { + if(error instanceof antlr4.error.RecognitionException) { + localctx.exception = error; + this._errHandler.reportError(this, error); + this._errHandler.recover(this, error); + } else { + throw error; + } + } finally { + <finallyAction> + this.unrollRecursionContexts(_parentctx) + } + return localctx; +}; + +>> + +CodeBlockForOuterMostAlt(currentOuterMostAltCodeBlock, locals, preamble, ops) ::= << +<if(currentOuterMostAltCodeBlock.altLabel)>localctx = new <currentOuterMostAltCodeBlock.altLabel; format="cap">Context(this, localctx);<endif> +this.enterOuterAlt(localctx, <currentOuterMostAltCodeBlock.alt.altNum>); +<CodeBlockForAlt(currentAltCodeBlock=currentOuterMostAltCodeBlock, ...)> +>> + +CodeBlockForAlt(currentAltCodeBlock, locals, preamble, ops) ::= << +<locals; separator="\n"> +<preamble; separator="\n"> +<ops; separator="\n"> +>> + +LL1AltBlock(choice, preamble, alts, error) ::= << +this.state = <choice.stateNumber>; +<!_errHandler.sync(this);!> +<if(choice.label)><labelref(choice.label)> = this._input.LT(1);<endif> +<preamble; separator="\n"> +switch(this._input.LA(1)) { +<choice.altLook,alts:{look,alt| <cases(ttypes=look)> + <alt> + break;}; separator="\n"> +default: + <error> +} +>> + +LL1OptionalBlock(choice, alts, error) ::= << +this.state = <choice.stateNumber>; +<!_errHandler.sync(this);!> +switch (this._input.LA(1)) { +<choice.altLook,alts:{look,alt| <cases(ttypes=look)> + <alt> + break;}; separator="\n"> +default: + <error> +} +>> + +LL1OptionalBlockSingleAlt(choice, expr, alts, preamble, error, followExpr) ::= << +this.state = <choice.stateNumber>; +<!_errHandler.sync(this);!> +<preamble; separator="\n"> +if(<expr>) { + <alts; separator="\n"> +} +<!else if ( !(<followExpr>) ) <error>!> +>> + +LL1StarBlockSingleAlt(choice, loopExpr, alts, preamble, iteration) ::= << +this.state = <choice.stateNumber>; +this._errHandler.sync(this); +<preamble; separator="\n"> +while(<loopExpr>) { + <alts; separator="\n"> + this.state = <choice.loopBackStateNumber>; + this._errHandler.sync(this); + <iteration> +} +>> + +LL1PlusBlockSingleAlt(choice, loopExpr, alts, preamble, iteration) ::= << +this.state = <choice.blockStartStateNumber>; <! alt block decision !> +this._errHandler.sync(this); +<preamble; separator="\n"> +do { + <alts; separator="\n"> + this.state = <choice.stateNumber>; <! loopback/exit decision !> + this._errHandler.sync(this); + <iteration> +} while(<loopExpr>); +>> + +// LL(*) stuff + +AltBlock(choice, preamble, alts, error) ::= << +this.state = <choice.stateNumber>; +<!_errHandler.sync(this);!> +<if(choice.label)><labelref(choice.label)> = _input.LT(1)<endif> +<preamble; separator="\n"> +var la_ = this._interp.adaptivePredict(this._input,<choice.decision>,this._ctx); +switch(la_) { +<alts:{alt | +case <i>: + <alt> + break; +}; separator="\n"> +} +>> + +OptionalBlock(choice, alts, error) ::= << +this.state = <choice.stateNumber>; +<!_errHandler.sync(this);!> +var la_ = this._interp.adaptivePredict(this._input,<choice.decision>,this._ctx); +<alts:{alt | +if(la_===<i><if(!choice.ast.greedy)>+1<endif>) { + <alt> +}; separator="\n} else "> +} +>> + +StarBlock(choice, alts, sync, iteration) ::= << +this.state = <choice.stateNumber>; +this._errHandler.sync(this); +var _alt = this._interp.adaptivePredict(this._input,<choice.decision>,this._ctx) +while(_alt!=<choice.exitAlt> && _alt!=antlr4.atn.ATN.INVALID_ALT_NUMBER) { + if(_alt===1<if(!choice.ast.greedy)>+1<endif>) { + <iteration> + <alts> <! should only be one !> + } + this.state = <choice.loopBackStateNumber>; + this._errHandler.sync(this); + _alt = this._interp.adaptivePredict(this._input,<choice.decision>,this._ctx); +} + +>> + +PlusBlock(choice, alts, error) ::= << +this.state = <choice.blockStartStateNumber>; <! alt block decision !> +this._errHandler.sync(this); +var _alt = 1<if(!choice.ast.greedy)>+1<endif>; +do { + switch (_alt) { + <alts:{alt| +case <i><if(!choice.ast.greedy)>+1<endif>: + <alt> + break;}; separator="\n"> + default: + <error> + } + this.state = <choice.loopBackStateNumber>; <! loopback/exit decision !> + this._errHandler.sync(this); + _alt = this._interp.adaptivePredict(this._input,<choice.decision>, this._ctx); +} while ( _alt!=<choice.exitAlt> && _alt!=antlr4.atn.ATN.INVALID_ALT_NUMBER ); +>> + +Sync(s) ::= "sync(<s.expecting.name>)" + +ThrowNoViableAlt(t) ::= "throw new antlr4.error.NoViableAltException(this);" + +TestSetInline(s) ::= << +<s.bitsets:{bits | <if(rest(rest(bits.ttypes)))><bitsetBitfieldComparison(s, bits)><else><bitsetInlineComparison(s, bits)><endif>}; separator=" || "> +>> + +// Javascript language spec - shift operators are 32 bits long max +testShiftInRange(shiftAmount) ::= << +((<shiftAmount>) & ~0x1f) == 0 +>> + +// produces smaller bytecode only when bits.ttypes contains more than two items +bitsetBitfieldComparison(s, bits) ::= <% +(<testShiftInRange({<offsetShiftVar(s.varName, bits.shift)>})> && ((1 \<\< <offsetShiftVar(s.varName, bits.shift)>) & (<bits.ttypes:{ttype | (1 \<\< <offsetShiftType(ttype, bits.shift)>)}; separator=" | ">)) !== 0) +%> + +isZero ::= [ +"0":true, +default:false +] + +offsetShiftVar(shiftAmount, offset) ::= <% +<if(!isZero.(offset))>(<shiftAmount> - <offset>)<else><shiftAmount><endif> +%> + +offsetShiftType(shiftAmount, offset) ::= <% +<if(!isZero.(offset))>(<parser.name>.<shiftAmount> - <offset>)<else><parser.name>.<shiftAmount><endif> +%> + +// produces more efficient bytecode when bits.ttypes contains at most two items +bitsetInlineComparison(s, bits) ::= <% +<bits.ttypes:{ttype | <s.varName>===<parser.name>.<ttype>}; separator=" || "> +%> + +cases(ttypes) ::= << +<ttypes:{t | case <parser.name>.<t>:}; separator="\n"> +>> + +InvokeRule(r, argExprsChunks) ::= << +this.state = <r.stateNumber>; +<if(r.labels)><r.labels:{l | <labelref(l)> = }><endif>this.<r.name>(<if(r.ast.options.p)><r.ast.options.p><if(argExprsChunks)>,<endif><endif><argExprsChunks>); +>> + +MatchToken(m) ::= << +this.state = <m.stateNumber>; +<if(m.labels)><m.labels:{l | <labelref(l)> = }><endif>this.match(<parser.name>.<m.name>); +>> + +MatchSet(m, expr, capture) ::= "<CommonSetStuff(m, expr, capture, false)>" + +MatchNotSet(m, expr, capture) ::= "<CommonSetStuff(m, expr, capture, true)>" + +CommonSetStuff(m, expr, capture, invert) ::= << +this.state = <m.stateNumber>; +<if(m.labels)><m.labels:{l | <labelref(l)> = }>this._input.LT(1);<endif> +<capture> +<if(invert)>if(<m.varName>\<=0 || <expr>)<else>if(!(<expr>))<endif> { + <if(m.labels)><m.labels:{l | <labelref(l)> = }><endif>this._errHandler.recoverInline(this); +} +else { + this.consume(); +} +>> + +Wildcard(w) ::= << +this.state = <w.stateNumber>; +<if(w.labels)><w.labels:{l | <labelref(l)> = }><endif>matchWildcard(); +>> + +// ACTION STUFF + +Action(a, foo, chunks) ::= "<chunks>" + +ArgAction(a, chunks) ::= "<chunks>" + +SemPred(p, chunks, failChunks) ::= << +this.state = <p.stateNumber>; +if (!( <chunks>)) { + throw new antlr4.error.FailedPredicateException(this, <p.predicate><if(failChunks)>, <failChunks><elseif(p.msg)>, <p.msg><endif>); +} +>> + +ExceptionClause(e, catchArg, catchAction) ::= << +catch (<catchArg>) { + <catchAction> +} +>> + +// lexer actions are not associated with model objects + +LexerSkipCommand() ::= "this.skip()" +LexerMoreCommand() ::= "this.more()" +LexerPopModeCommand() ::= "this.popMode()" +LexerTypeCommand(arg) ::= "this._type = <arg>" +LexerChannelCommand(arg) ::= "this._channel = <arg>" +LexerModeCommand(arg) ::= "this._mode = <arg>" +LexerPushModeCommand(arg) ::= "this.pushMode(<arg>)" + +ActionText(t) ::= "<t.text>" +ActionTemplate(t) ::= "<t.st>" +ArgRef(a) ::= "localctx.<a.name>" +LocalRef(a) ::= "localctx.<a.name>" +RetValueRef(a) ::= "localctx.<a.name>" +QRetValueRef(a) ::= "<ctx(a)>.<a.dict>.<a.name>" +/** How to translate $tokenLabel */ +TokenRef(t) ::= "<ctx(t)>.<t.name>" +LabelRef(t) ::= "<ctx(t)>.<t.name>" +ListLabelRef(t) ::= "<ctx(t)>.<ListLabelName(t.name)>" +SetAttr(s,rhsChunks) ::= "<ctx(s)>.<s.name> = <rhsChunks>" + +TokenLabelType() ::= "<file.TokenLabelType; null={Token}>" +InputSymbolType() ::= "<file.InputSymbolType; null={Token}>" + +TokenPropertyRef_text(t) ::= "(<ctx(t)>.<t.label>===null ? null : <ctx(t)>.<t.label>.text)" +TokenPropertyRef_type(t) ::= "(<ctx(t)>.<t.label> === null ? 0 : <ctx(t)>.<t.label>.type)" +TokenPropertyRef_line(t) ::= "(<ctx(t)>.<t.label> === null ? 0 : <ctx(t)>.<t.label>.line)" +TokenPropertyRef_pos(t) ::= "(<ctx(t)>.<t.label> === null ? 0 : <ctx(t)>.<t.label>.column)" +TokenPropertyRef_channel(t) ::= "(<ctx(t)>.<t.label> === null ? 0 : <ctx(t)>.<t.label>.channel)" +TokenPropertyRef_index(t) ::= "(<ctx(t)>.<t.label> === null ? 0 : <ctx(t)>.<t.label>.tokenIndex)" +TokenPropertyRef_int(t) ::= "(<ctx(t)>.<t.label> === null ? 0 : parseInt(<ctx(t)>.<t.label>.text))" + +RulePropertyRef_start(r) ::= "(<ctx(r)>.<r.label>===null ? null : <ctx(r)>.<r.label>.start)" +RulePropertyRef_stop(r) ::= "(<ctx(r)>.<r.label>===null ? null : <ctx(r)>.<r.label>.stop)" +RulePropertyRef_text(r) ::= "(<ctx(r)>.<r.label>===null ? null : this._input.getText(new antlr4.Interval(<ctx(r)>.<r.label>.start,<ctx(r)>.<r.label>.stop)))" +RulePropertyRef_ctx(r) ::= "<ctx(r)>.<r.label>" +RulePropertyRef_parser(r) ::= "this" + +ThisRulePropertyRef_start(r) ::= "localctx.start" +ThisRulePropertyRef_stop(r) ::= "localctx.stop" +ThisRulePropertyRef_text(r) ::= "this._input.getText(new antlr4.Interval(localctx.start, this._input.LT(-1)))" +ThisRulePropertyRef_ctx(r) ::= "localctx" +ThisRulePropertyRef_parser(r) ::= "this" + +NonLocalAttrRef(s) ::= "getInvokingContext(<s.ruleIndex>).<s.name>" +SetNonLocalAttr(s, rhsChunks) ::= "getInvokingContext(<s.ruleIndex>).<s.name> = <rhsChunks>" + +AddToLabelList(a) ::= "<ctx(a.label)>.<a.listName>.push(<labelref(a.label)>);" + +TokenDecl(t) ::= "this.<t.name> = null; // <TokenLabelType()>" +TokenTypeDecl(t) ::= "var <t.name> = 0; // <TokenLabelType()> type" +TokenListDecl(t) ::= "this.<t.name> = []; // of <TokenLabelType()>s" +RuleContextDecl(r) ::= "this.<r.name> = null; // <r.ctxName>" +RuleContextListDecl(rdecl) ::= "this.<rdecl.name> = []; // of <rdecl.ctxName>s" + +ContextTokenGetterDecl(t) ::= << +<t.name> = function() { + return this.getToken(<parser.name>.<t.name>, 0); +}; +>> + +// should never be called +ContextTokenListGetterDecl(t) ::= << +def <t.name>_list(self): + return self.getTokens(<parser.name>.<t.name>) +>> + +ContextTokenListIndexedGetterDecl(t) ::= << +<t.name> = function(i) { + if(i===undefined) { + i = null; + } + if(i===null) { + return this.getTokens(<parser.name>.<t.name>); + } else { + return this.getToken(<parser.name>.<t.name>, i); + } +}; + +>> + +ContextRuleGetterDecl(r) ::= << +<r.name> = function() { + return this.getTypedRuleContext(<r.ctxName>,0); +}; +>> + +// should never be called +ContextRuleListGetterDecl(r) ::= << +def <r.name>_list(self): + return self.getTypedRuleContexts(<parser.name>.<r.ctxName>) + +>> + +ContextRuleListIndexedGetterDecl(r) ::= << +<r.name> = function(i) { + if(i===undefined) { + i = null; + } + if(i===null) { + return this.getTypedRuleContexts(<r.ctxName>); + } else { + return this.getTypedRuleContext(<r.ctxName>,i); + } +}; +>> + +LexerRuleContext() ::= "RuleContext" + +/** The rule context name is the rule followed by a suffix; e.g., + * r becomes rContext. + */ +RuleContextNameSuffix() ::= "Context" + +ImplicitTokenLabel(tokenName) ::= "_<tokenName>" +ImplicitRuleLabel(ruleName) ::= "_<ruleName>" +ImplicitSetLabel(id) ::= "_tset<id>" +ListLabelName(label) ::= "<label>" + +CaptureNextToken(d) ::= "<d.varName> = self._input.LT(1)" +CaptureNextTokenType(d) ::= "<d.varName> = this._input.LA(1);" + +StructDecl(struct,ctorAttrs,attrs,getters,dispatchMethods,interfaces,extensionMembers, + superClass={antlr4.ParserRuleContext}) ::= << +function <struct.name>(parser, parent, invokingState<struct.ctorAttrs:{a | , <a.name>}>) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + <superClass>.call(this, parent, invokingState); + this.parser = parser; + this.ruleIndex = <parser.name>.RULE_<struct.derivedFromName>; + <attrs:{a | <a>}; separator="\n"> + <struct.ctorAttrs:{a | this.<a.name> = <a.name> || null;}; separator="\n"> + return this; +} + +<struct.name>.prototype = Object.create(<superClass>.prototype); +<struct.name>.prototype.constructor = <struct.name>; + +<getters:{g | <struct.name>.prototype.<g>}; separator="\n\n"> + +<if(struct.provideCopyFrom)> <! don't need copy unless we have subclasses !> +<struct.name>.prototype.copyFrom = function(ctx) { + <superClass>.prototype.copyFrom.call(this, ctx); + <struct.attrs:{a | this.<a.name> = ctx.<a.name>;}; separator="\n"> +}; +<endif> +<dispatchMethods; separator="\n"> +<extensionMembers; separator="\n"> + +>> + +AltLabelStructDecl(struct,attrs,getters,dispatchMethods) ::= << +function <struct.name>(parser, ctx) { + <currentRule.name; format="cap">Context.call(this, parser); + <attrs:{a | <a>;}; separator="\n"> + <currentRule.name; format="cap">Context.prototype.copyFrom.call(this, ctx); + return this; +} + +<struct.name>.prototype = Object.create(<currentRule.name; format="cap">Context.prototype); +<struct.name>.prototype.constructor = <struct.name>; + +<! Define fields of this parser to export this struct/context class !> +<parser.name>.<struct.name> = <struct.name>; + +<getters:{g | <struct.name>.prototype.<g>}; separator="\n\n"> +<dispatchMethods; separator="\n"> + +>> + +ListenerDispatchMethod(method) ::= << +<struct.name>.prototype.<if(method.isEnter)>enter<else>exit<endif>Rule = function(listener) { + if(listener instanceof <parser.grammarName>Listener ) { + listener.<if(method.isEnter)>enter<else>exit<endif><struct.derivedFromName; format="cap">(this); + } +}; + +>> + +VisitorDispatchMethod(method) ::= << +<struct.name>.prototype.accept = function(visitor) { + if ( visitor instanceof <parser.grammarName>Visitor ) { + return visitor.visit<struct.derivedFromName; format="cap">(this); + } else { + return visitor.visitChildren(this); + } +}; + +>> + +AttributeDecl(d) ::= "this.<d.name> = <if(d.initValue)><d.initValue><else>null<endif>" + +/** If we don't know location of label def x, use this template */ +labelref(x) ::= "<if(!x.isLocal)>localctx.<endif><x.name>" + +/** For any action chunk, what is correctly-typed context struct ptr? */ +ctx(actionChunk) ::= "localctx" + +// used for left-recursive rules +recRuleAltPredicate(ruleName,opPrec) ::= "this.precpred(this._ctx, <opPrec>)" +recRuleSetReturnAction(src,name) ::= "$<name>=$<src>.<name>" +recRuleSetStopToken() ::= "this._ctx.stop = this._input.LT(-1);" + +recRuleAltStartAction(ruleName, ctxName, label) ::= << +localctx = new <ctxName>Context(this, _parentctx, _parentState); +<if(label)>localctx.<label> = _prevctx;<endif> +this.pushNewRecursionContext(localctx, _startState, <parser.name>.RULE_<ruleName>); +>> + +recRuleLabeledAltStartAction(ruleName, currentAltLabel, label, isListLabel) ::= << +localctx = new <currentAltLabel; format="cap">Context(this, new <ruleName; format="cap">Context(this, _parentctx, _parentState)); +<if(label)> +<if(isListLabel)> +localctx.<label>.push(_prevctx); +<else> +localctx.<label> = _prevctx; +<endif> +<endif> +this.pushNewRecursionContext(localctx, _startState, <parser.name>.RULE_<ruleName>); +>> + +recRuleReplaceContext(ctxName) ::= << +localctx = new <ctxName>Context(this, localctx); +this._ctx = localctx; +_prevctx = localctx; +>> + +recRuleSetPrevCtx() ::= << +if(this._parseListeners!==null) { + this.triggerExitRuleEvent(); +} +_prevctx = localctx; +>> + + +LexerFile(lexerFile, lexer, namedActions) ::= << +<fileHeader(lexerFile.grammarFileName, lexerFile.ANTLRVersion)> +var antlr4 = require('antlr4/index'); + +<namedActions.header> + +<lexer> + +>> + +Lexer(lexer, atn, actionFuncs, sempredFuncs, superClass) ::= << + +<atn> + +var atn = new antlr4.atn.ATNDeserializer().deserialize(serializedATN); + +var decisionsToDFA = atn.decisionToState.map( function(ds, index) { return new antlr4.dfa.DFA(ds, index); }); + +function <lexer.name>(input) { + <if(superClass)><superClass><else>antlr4.Lexer<endif>.call(this, input); + this._interp = new antlr4.atn.LexerATNSimulator(this, atn, decisionsToDFA, new antlr4.PredictionContextCache()); + return this; +} + +<lexer.name>.prototype = Object.create(<if(superClass)><superClass><else>antlr4.Lexer<endif>.prototype); +<lexer.name>.prototype.constructor = <lexer.name>; + +<lexer.name>.EOF = antlr4.Token.EOF; +<lexer.tokens:{k | <lexer.name>.<k> = <lexer.tokens.(k)>;}; separator="\n", wrap, anchor> + +<rest(lexer.modes):{m| <lexer.name>.<m> = <i>;}; separator="\n"> + +<lexer.name>.modeNames = [ <lexer.modes:{m| "<m>"}; separator=", ", wrap, anchor> ]; + +<lexer.name>.literalNames = [ <lexer.literalNames:{t | <t>}; null="'null'", separator=", ", wrap, anchor> ]; + +<lexer.name>.symbolicNames = [ <lexer.symbolicNames:{t | <t>}; null="'null'", separator=", ", wrap, anchor> ]; + +<lexer.name>.ruleNames = [ <lexer.ruleNames:{r | "<r>"}; separator=", ", wrap, anchor> ]; + +<lexer.name>.grammarFileName = "<lexer.grammarFileName>"; + +<namedActions.members> + +<dumpActions(lexer, "", actionFuncs, sempredFuncs)> + +exports.<lexer.name> = <lexer.name>; + +>> + +SerializedATN(model) ::= << +<! only one segment, can be inlined !> + +var serializedATN = ["<model.serialized; wrap={",<\n> "}>"].join(""); + +>> + +/** 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) ::= << +<javaTypeInitMap.(typeName)> +>> + +codeFileExtension() ::= ".js" diff --git a/tool/resources/org/antlr/v4/tool/templates/codegen/Python2/Python2.stg b/tool/resources/org/antlr/v4/tool/templates/codegen/Python2/Python2.stg new file mode 100644 index 0000000..b4e66eb --- /dev/null +++ b/tool/resources/org/antlr/v4/tool/templates/codegen/Python2/Python2.stg @@ -0,0 +1,805 @@ +/* + * [The "BSD license"] + * Copyright (c) 2012 Terence Parr + * Copyright (c) 2012 Sam Harwell + * Copyright (c) 2014 Eric Vergnaud + * 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. + */ + +/** ANTLR tool checks output templates are compatible with tool code generation. + * For now, a simple string match used on x.y of x.y.z scheme. + * Must match Tool.VERSION during load to templates. + * + * REQUIRED. + */ + +pythonTypeInitMap ::= [ + "bool":"False", + "int":"0", + "float":"0.0", + "str":"", + default:"None" // anything other than a primitive type is an object +] + +// args must be <object-model-object>, <fields-resulting-in-STs> + +ParserFile(file, parser, namedActions) ::= << +<fileHeader(file.grammarFileName, file.ANTLRVersion)> +# encoding: utf-8 +from __future__ import print_function +from antlr4 import * +from io import StringIO + +<namedActions.header> +<parser> + +>> + +ListenerFile(file, header) ::= << +<fileHeader(file.grammarFileName, file.ANTLRVersion)> +from antlr4 import * +<header> + +# This class defines a complete listener for a parse tree produced by <file.parserName>. +class <file.grammarName>Listener(ParseTreeListener): + + <file.listenerNames:{lname | +# Enter a parse tree produced by <file.parserName>#<lname>. +def enter<lname; format="cap">(self, ctx): + pass + +# Exit a parse tree produced by <file.parserName>#<lname>. +def exit<lname; format="cap">(self, ctx): + pass + +}; separator="\n"> + +>> + + +VisitorFile(file, header) ::= << +<fileHeader(file.grammarFileName, file.ANTLRVersion)> +from antlr4 import * +<header> + +# This class defines a complete generic visitor for a parse tree produced by <file.parserName>. + +class <file.grammarName>Visitor(ParseTreeVisitor): + + <file.visitorNames:{lname | +# Visit a parse tree produced by <file.parserName>#<lname>. +def visit<lname; format="cap">(self, ctx): + return self.visitChildren(ctx) + +}; separator="\n"> + +>> + + +fileHeader(grammarFileName, ANTLRVersion) ::= << +# Generated from <grammarFileName> by ANTLR <ANTLRVersion> +>> + +Parser(parser, funcs, atn, sempredFuncs, superClass) ::= << +<Parser_(ctor="parser_ctor", ...)> +>> + +Parser_(parser, funcs, atn, sempredFuncs, ctor, superClass) ::= << +<if(superClass)> +from .<superClass> import <superClass> + +<endif> +<atn> + +class <parser.name> ( <if(superClass)><superClass><else>Parser<endif> ): + + grammarFileName = "<parser.grammarFileName>" + + atn = ATNDeserializer().deserialize(serializedATN()) + + decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ] + + sharedContextCache = PredictionContextCache() + + literalNames = [ <parser.literalNames:{t | u<t>}; null="u\"\<INVALID>\"", separator=", ", wrap, anchor> ] + + symbolicNames = [ <parser.symbolicNames:{t | u<t>}; null="u\"\<INVALID>\"", separator=", ", wrap, anchor> ] + + <parser.rules:{r | RULE_<r.name> = <r.index>}; separator="\n", wrap, anchor> + + ruleNames = [ <parser.ruleNames:{r | u"<r>"}; separator=", ", wrap, anchor> ] + + EOF = <TokenLabelType()>.EOF + <if(parser.tokens)> + <parser.tokens:{k | <k>=<parser.tokens.(k)>}; separator="\n", wrap, anchor> + <endif> + + <parser:(ctor)()> + + <namedActions.members> + + <funcs; separator="\n"> + + +<if(sempredFuncs)> + def sempred(self, localctx, ruleIndex, predIndex): + if self._predicates == None: + self._predicates = dict() +<parser.sempredFuncs.values:{f | + self._predicates[<f.ruleIndex>] = self.<f.name>_sempred}; separator="\n "> + pred = self._predicates.get(ruleIndex, None) + if pred is None: + raise Exception("No predicate with index:" + str(ruleIndex)) + else: + return pred(localctx, predIndex) + + <sempredFuncs.values; separator="\n"> +<endif> + + + +>> + +dumpActions(recog, argFuncs, actionFuncs, sempredFuncs) ::= << +<if(actionFuncs)> +def action(self, localctx, ruleIndex, actionIndex): + if self._actions is None: + actions = dict() +<recog.actionFuncs.values:{f| + actions[<f.ruleIndex>] = self.<f.name>_action }; separator="\n"> + self._actions = actions + action = self._actions.get(ruleIndex, None) + if action is not None: + action(localctx, actionIndex) + else: + raise Exception("No registered action for:" + str(ruleIndex)) + +<actionFuncs.values; separator="\n"> + +<endif> +<if(sempredFuncs)> +def sempred(self, localctx, ruleIndex, predIndex): + if self._predicates is None: + preds = dict() +<recog.sempredFuncs.values:{f| + preds[<f.ruleIndex>] = self.<f.name>_sempred}; separator="\n"> + self._predicates = preds + pred = self._predicates.get(ruleIndex, None) + if pred is not None: + return pred(localctx, predIndex) + else: + raise Exception("No registered predicate for:" + str(ruleIndex)) + +<sempredFuncs.values; separator="\n"> +<endif> +>> + +parser_ctor(p) ::= << +def __init__(self, input): + super(<parser.name>, self).__init__(input) + self.checkVersion("<file.ANTLRVersion>") + self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache) + self._predicates = None + +>> + +/* This generates a private method since the actionIndex is generated, making an + * overriding implementation impossible to maintain. + */ +RuleActionFunction(r, actions) ::= << + +def <r.name>_action(self, localctx , actionIndex): +<actions:{index| +<if(first(actions))> + if actionIndex == <index>: + <actions.(index)> +<elseif(rest(actions))> + elif actionIndex == <index>: + <actions.(index)> +<endif> }; separator="\n"> +>> + +/* This generates a private method since the predIndex is generated, making an + * overriding implementation impossible to maintain. + */ +RuleSempredFunction(r, actions) ::= << +def <r.name>_sempred(self, localctx, predIndex): + <actions:{index| +<if(first(actions))> + if predIndex == <index>: + return <actions.(index)> +<elseif(rest(actions))> + elif predIndex == <index>: + return <actions.(index)> +<endif> }; separator="\n"> + +>> + +RuleFunction(currentRule,args,code,locals,ruleCtx,altLabelCtxs,namedActions,finallyAction,postamble,exceptions) ::= << + +<ruleCtx> + +<altLabelCtxs:{l | <altLabelCtxs.(l)>}; separator="\n"> + +def <currentRule.name>(self<currentRule.args:{a | , <a.name>}>): + + localctx = <parser.name>.<currentRule.ctxType>(self, self._ctx, self.state<currentRule.args:{a | , <a.name>}>) + self.enterRule(localctx, <currentRule.startState>, self.RULE_<currentRule.name>) + <namedActions.init> + <locals; separator="\n"> + try: + <code> + <postamble; separator="\n"> + <namedActions.after> + <if(exceptions)> + <exceptions; separator="\n"> + <else> + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + <endif> + finally: + <finallyAction> + self.exitRule() + return localctx + +>> + +LeftRecursiveRuleFunction(currentRule,args,code,locals,ruleCtx,altLabelCtxs, + namedActions,finallyAction,postamble) ::= +<< + +<ruleCtx> +<altLabelCtxs:{l | <altLabelCtxs.(l)>}; separator="\n"> + +def <currentRule.name>(self, _p=0<if(currentRule.args)>, <args:{a | , <a>}><endif>): + _parentctx = self._ctx + _parentState = self.state + localctx = <parser.name>.<currentRule.ctxType>(self, self._ctx, _parentState<args:{a | , <a.name>}>) + _prevctx = localctx + _startState = <currentRule.startState> + self.enterRecursionRule(localctx, <currentRule.startState>, self.RULE_<currentRule.name>, _p) + <namedActions.init> + <locals; separator="\n"> + try: + <code> + <postamble; separator="\n"> + <namedActions.after> + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + <finallyAction> + self.unrollRecursionContexts(_parentctx) + return localctx + +>> + +CodeBlockForOuterMostAlt(currentOuterMostAltCodeBlock, locals, preamble, ops) ::= << +<if(currentOuterMostAltCodeBlock.altLabel)>localctx = <parser.name>.<currentOuterMostAltCodeBlock.altLabel; format="cap">Context(self, localctx)<endif> +self.enterOuterAlt(localctx, <currentOuterMostAltCodeBlock.alt.altNum>) +<CodeBlockForAlt(currentAltCodeBlock=currentOuterMostAltCodeBlock, ...)> +>> + +CodeBlockForAlt(currentAltCodeBlock, locals, preamble, ops) ::= << +<locals; separator="\n"> +<preamble; separator="\n"> +<ops; separator="\n"> +>> + +LL1AltBlock(choice, preamble, alts, error) ::= << +self.state = <choice.stateNumber> +<!_errHandler.sync(this);!> +<if(choice.label)><labelref(choice.label)> = _input.LT(1)<endif> +<preamble; separator="\n"> +token = self._input.LA(1) +<choice.altLook,alts:{look,alt| <cases(ttypes=look)> + <alt> + }; separator="\nel"> +else: + <error> + +>> + +LL1OptionalBlock(choice, alts, error) ::= << +self.state = <choice.stateNumber> +<!_errHandler.sync(this);!> +token = self._input.LA(1) +<choice.altLook,alts:{look,alt| <cases(ttypes=look)> + <alt> + pass}; separator="\nel"> +else: + <error> +>> + +LL1OptionalBlockSingleAlt(choice, expr, alts, preamble, error, followExpr) ::= << +self.state = <choice.stateNumber> +<!_errHandler.sync(this);!> +<preamble; separator="\n"> +if <expr>: + <alts; separator="\n"> + +<!else if ( !(<followExpr>) ) <error>!> +>> + + +LL1StarBlockSingleAlt(choice, loopExpr, alts, preamble, iteration) ::= << +self.state = <choice.stateNumber> +self._errHandler.sync(self) +<preamble; separator="\n"> +while <loopExpr>: + <alts; separator="\n"> + self.state = <choice.loopBackStateNumber> + self._errHandler.sync(self) + <iteration> + +>> + +LL1PlusBlockSingleAlt(choice, loopExpr, alts, preamble, iteration) ::= << +self.state = <choice.blockStartStateNumber> <! alt block decision !> +self._errHandler.sync(self) +<preamble; separator="\n"> +while True: + <alts; separator="\n"> + self.state = <choice.stateNumber> <! loopback/exit decision !> + self._errHandler.sync(self) + <iteration> + if not (<loopExpr>): + break + +>> + +// LL(*) stuff + +AltBlock(choice, preamble, alts, error) ::= << +self.state = <choice.stateNumber> +<!_errHandler.sync(this);!> +<if(choice.label)><labelref(choice.label)> = _input.LT(1)<endif> +<preamble; separator="\n"> +la_ = self._interp.adaptivePredict(self._input,<choice.decision>,self._ctx) +<alts:{alt | +if la_ == <i>: + <alt> + pass +}; separator="\nel"> + +>> + +OptionalBlock(choice, alts, error) ::= << +self.state = <choice.stateNumber> +<!_errHandler.sync(this);!> +la_ = self._interp.adaptivePredict(self._input,<choice.decision>,self._ctx) +<alts:{alt | +if la_ == <i><if(!choice.ast.greedy)>+1<endif>: + <alt> +}; separator="\nel"> + +>> + +StarBlock(choice, alts, sync, iteration) ::= << +self.state = <choice.stateNumber> +self._errHandler.sync(self) +_alt = self._interp.adaptivePredict(self._input,<choice.decision>,self._ctx) +while _alt!=<choice.exitAlt> and _alt!=ATN.INVALID_ALT_NUMBER: + if _alt==1<if(!choice.ast.greedy)>+1<endif>: + <iteration> + <alts> <! should only be one !> + self.state = <choice.loopBackStateNumber> + self._errHandler.sync(self) + _alt = self._interp.adaptivePredict(self._input,<choice.decision>,self._ctx) + +>> + +PlusBlock(choice, alts, error) ::= << +self.state = <choice.blockStartStateNumber> <! alt block decision !> +self._errHandler.sync(self) +_alt = 1<if(!choice.ast.greedy)>+1<endif> +while _alt!=<choice.exitAlt> and _alt!=ATN.INVALID_ALT_NUMBER: + <alts:{alt| +if _alt == <i><if(!choice.ast.greedy)>+1<endif>: + <alt> +}; separator="\nel"> + else: + <error> + self.state = <choice.loopBackStateNumber> <! loopback/exit decision !> + self._errHandler.sync(self) + _alt = self._interp.adaptivePredict(self._input,<choice.decision>,self._ctx) + +>> + +Sync(s) ::= "sync(<s.expecting.name>)" + +ThrowNoViableAlt(t) ::= "raise NoViableAltException(self)" + +TestSetInline(s) ::= << +<s.bitsets:{bits | <if(rest(rest(bits.ttypes)))><bitsetBitfieldComparison(s, bits)><else><bitsetInlineComparison(s, bits)><endif>}; separator=" or "> +>> + +// Java language spec 15.19 - shift operators mask operands rather than overflow to 0... need range test +testShiftInRange(shiftAmount) ::= << +((<shiftAmount>) & ~0x3f) == 0 +>> + +// produces smaller bytecode only when bits.ttypes contains more than two items +bitsetBitfieldComparison(s, bits) ::= <% +(<testShiftInRange({<offsetShiftVar(s.varName, bits.shift)>})> and ((1 \<\< <offsetShiftVar(s.varName, bits.shift)>) & (<bits.ttypes:{ttype | (1 \<\< <offsetShiftType(ttype, bits.shift)>)}; separator=" | ">)) != 0) +%> + +isZero ::= [ +"0":true, +default:false +] + +offsetShiftVar(shiftAmount, offset) ::= <% +<if(!isZero.(offset))>(<shiftAmount> - <offset>)<else><shiftAmount><endif> +%> + +offsetShiftType(shiftAmount, offset) ::= <% +<if(!isZero.(offset))>(<parser.name>.<shiftAmount> - <offset>)<else><parser.name>.<shiftAmount><endif> +%> + +// produces more efficient bytecode when bits.ttypes contains at most two items +bitsetInlineComparison(s, bits) ::= <% +<bits.ttypes:{ttype | <s.varName>==<parser.name>.<ttype>}; separator=" or "> +%> + +cases(ttypes) ::= << +if token in [<ttypes:{t | <parser.name>.<t>}; separator=", ">]: +>> + +InvokeRule(r, argExprsChunks) ::= << +self.state = <r.stateNumber> +<if(r.labels)><r.labels:{l | <labelref(l)> = }><endif>self.<r.name>(<if(r.ast.options.p)><r.ast.options.p><if(argExprsChunks)>,<endif><endif><argExprsChunks>) +>> + +MatchToken(m) ::= << +self.state = <m.stateNumber> +<if(m.labels)><m.labels:{l | <labelref(l)> = }><endif>self.match(<parser.name>.<m.name>) +>> + +MatchSet(m, expr, capture) ::= "<CommonSetStuff(m, expr, capture, false)>" + +MatchNotSet(m, expr, capture) ::= "<CommonSetStuff(m, expr, capture, true)>" + +CommonSetStuff(m, expr, capture, invert) ::= << +self.state = <m.stateNumber> +<if(m.labels)><m.labels:{l | <labelref(l)> = }>self._input.LT(1)<endif> +<capture> +<if(invert)>if <m.varName> \<= 0 or <expr><else>if not(<expr>)<endif>: +<if(m.labels)><m.labels:{l | <labelref(l)> = }><else> <endif>self._errHandler.recoverInline(self) +else: + self.consume() +>> + +Wildcard(w) ::= << +self.state = <w.stateNumber> +<if(w.labels)><w.labels:{l | <labelref(l)> = }><endif>self.matchWildcard() +>> + +// ACTION STUFF + +Action(a, foo, chunks) ::= "<chunks>" + +ArgAction(a, chunks) ::= "<chunks>" + +SemPred(p, chunks, failChunks) ::= << +self.state = <p.stateNumber> +if not <chunks>: + from antlr4.error.Errors import FailedPredicateException + raise FailedPredicateException(self, <p.predicate><if(failChunks)>, <failChunks><elseif(p.msg)>, <p.msg><endif>) +>> + +ExceptionClause(e, catchArg, catchAction) ::= << +catch (<catchArg>) { + <catchAction> +} +>> + +// lexer actions are not associated with model objects + +LexerSkipCommand() ::= "skip()" +LexerMoreCommand() ::= "more()" +LexerPopModeCommand() ::= "popMode()" + +LexerTypeCommand(arg) ::= "_type = <arg>" +LexerChannelCommand(arg) ::= "_channel = <arg>" +LexerModeCommand(arg) ::= "_mode = <arg>" +LexerPushModeCommand(arg) ::= "pushMode(<arg>)" + +ActionText(t) ::= "<t.text>" +ActionTemplate(t) ::= "<t.st>" +ArgRef(a) ::= "localctx.<a.name>" +LocalRef(a) ::= "localctx.<a.name>" +RetValueRef(a) ::= "localctx.<a.name>" +QRetValueRef(a) ::= "<ctx(a)>.<a.dict>.<a.name>" +/** How to translate $tokenLabel */ +TokenRef(t) ::= "<ctx(t)>.<t.name>" +LabelRef(t) ::= "<ctx(t)>.<t.name>" +ListLabelRef(t) ::= "<ctx(t)>.<ListLabelName(t.name)>" +SetAttr(s,rhsChunks) ::= "<ctx(s)>.<s.name> = <rhsChunks>" + +TokenLabelType() ::= "<file.TokenLabelType; null={Token}>" +InputSymbolType() ::= "<file.InputSymbolType; null={Token}>" + +TokenPropertyRef_text(t) ::= "(None if <ctx(t)>.<t.label> is None else <ctx(t)>.<t.label>.text)" +TokenPropertyRef_type(t) ::= "(0 if <ctx(t)>.<t.label> is None else <ctx(t)>.<t.label>.type()" +TokenPropertyRef_line(t) ::= "(0 if <ctx(t)>.<t.label> is None else <ctx(t)>.<t.label>.line)" +TokenPropertyRef_pos(t) ::= "(0 if <ctx(t)>.<t.label> is None else <ctx(t)>.<t.label>.column)" +TokenPropertyRef_channel(t) ::= "(0 if (<ctx(t)>.<t.label> is None else <ctx(t)>.<t.label>.channel)" +TokenPropertyRef_index(t) ::= "(0 if <ctx(t)>.<t.label> is None else <ctx(t)>.<t.label>.tokenIndex)" +TokenPropertyRef_int(t) ::= "(0 if <ctx(t)>.<t.label> is None else int(<ctx(t)>.<t.label>.text))" + +RulePropertyRef_start(r) ::= "(None if <ctx(r)>.<r.label> is None else <ctx(r)>.<r.label>.start)" +RulePropertyRef_stop(r) ::= "(None if <ctx(r)>.<r.label> is None else <ctx(r)>.<r.label>.stop)" +RulePropertyRef_text(r) ::= "(None if <ctx(r)>.<r.label> is None else self._input.getText((<ctx(r)>.<r.label>.start,<ctx(r)>.<r.label>.stop)))" +RulePropertyRef_ctx(r) ::= "<ctx(r)>.<r.label>" +RulePropertyRef_parser(r) ::= "self" + +ThisRulePropertyRef_start(r) ::= "localctx.start" +ThisRulePropertyRef_stop(r) ::= "localctx.stop" +ThisRulePropertyRef_text(r) ::= "self._input.getText((localctx.start, self._input.LT(-1)))" +ThisRulePropertyRef_ctx(r) ::= "localctx" +ThisRulePropertyRef_parser(r) ::= "self" + +NonLocalAttrRef(s) ::= "getInvokingContext(<s.ruleIndex>).<s.name>" +SetNonLocalAttr(s, rhsChunks) ::= "getInvokingContext(<s.ruleIndex>).<s.name> = <rhsChunks>" + +AddToLabelList(a) ::= "<ctx(a.label)>.<a.listName>.append(<labelref(a.label)>)" + +TokenDecl(t) ::= "self.<t.name> = None # <TokenLabelType()>" +TokenTypeDecl(t) ::= "self.<t.name> = 0 # <TokenLabelType()> type" +TokenListDecl(t) ::= "self.<t.name> = list() # of <TokenLabelType()>s" +RuleContextDecl(r) ::= "self.<r.name> = None # <r.ctxName>" +RuleContextListDecl(rdecl) ::= "self.<rdecl.name> = list() # of <rdecl.ctxName>s" + +ContextTokenGetterDecl(t) ::= << +def <t.name>(self): + return self.getToken(<parser.name>.<t.name>, 0) +>> + +// should never be called +ContextTokenListGetterDecl(t) ::= << +def <t.name>_list(self): + return self.getTokens(<parser.name>.<t.name>) +>> + +ContextTokenListIndexedGetterDecl(t) ::= << +def <t.name>(self, i=None): + if i is None: + return self.getTokens(<parser.name>.<t.name>) + else: + return self.getToken(<parser.name>.<t.name>, i) +>> + +ContextRuleGetterDecl(r) ::= << +def <r.name>(self): + return self.getTypedRuleContext(<parser.name>.<r.ctxName>,0) + +>> + +// should never be called +ContextRuleListGetterDecl(r) ::= << +def <r.name>_list(self): + return self.getTypedRuleContexts(<parser.name>.<r.ctxName>) + +>> + +ContextRuleListIndexedGetterDecl(r) ::= << +def <r.name>(self, i=None): + if i is None: + return self.getTypedRuleContexts(<parser.name>.<r.ctxName>) + else: + return self.getTypedRuleContext(<parser.name>.<r.ctxName>,i) + +>> + +LexerRuleContext() ::= "RuleContext" + +/** The rule context name is the rule followed by a suffix; e.g., + * r becomes rContext. + */ +RuleContextNameSuffix() ::= "Context" + +ImplicitTokenLabel(tokenName) ::= "_<tokenName>" +ImplicitRuleLabel(ruleName) ::= "_<ruleName>" +ImplicitSetLabel(id) ::= "_tset<id>" +ListLabelName(label) ::= "<label>" + +CaptureNextToken(d) ::= "<d.varName> = self._input.LT(1)" +CaptureNextTokenType(d) ::= "<d.varName> = self._input.LA(1)" + +StructDecl(struct,ctorAttrs,attrs,getters,dispatchMethods,interfaces,extensionMembers, + superClass={ParserRuleContext}) ::= << +class <struct.name>(<superClass>): + + def __init__(self, parser, parent=None, invokingState=-1<struct.ctorAttrs:{a | , <a.name>=None}>): + super(<parser.name>.<struct.name>, self).__init__(parent, invokingState) + self.parser = parser + <attrs:{a | <a>}; separator="\n"> + <struct.ctorAttrs:{a | self.<a.name> = <a.name>}; separator="\n"> + + <getters:{g | <g>}; separator="\n\n"> + + def getRuleIndex(self): + return <parser.name>.RULE_<struct.derivedFromName> + +<if(struct.provideCopyFrom)> <! don't need copy unless we have subclasses !> + def copyFrom(self, ctx): + super(<parser.name>.<struct.name>, self).copyFrom(ctx) + <struct.attrs:{a | self.<a.name> = ctx.<a.name>}; separator="\n"> + +<endif> + <dispatchMethods; separator="\n"> + <extensionMembers; separator="\n"> + +>> + +AltLabelStructDecl(struct,attrs,getters,dispatchMethods) ::= << +class <struct.name>(<currentRule.name; format="cap">Context): + + def __init__(self, parser, ctx): # actually a <parser.name>.<currentRule.name; format="cap">Context) + super(<parser.name>.<struct.name>, self).__init__(parser) + <attrs:{a | <a>}; separator="\n"> + self.copyFrom(ctx) + + <getters:{g | <g>}; separator="\n"> + + <dispatchMethods; separator="\n"> + +>> + +ListenerDispatchMethod(method) ::= << +def <if(method.isEnter)>enter<else>exit<endif>Rule(self, listener): + if hasattr(listener, "<if(method.isEnter)>enter<else>exit<endif><struct.derivedFromName; format="cap">"): + listener.<if(method.isEnter)>enter<else>exit<endif><struct.derivedFromName; format="cap">(self) + +>> + +VisitorDispatchMethod(method) ::= << +def accept(self, visitor): + if hasattr(visitor, "visit<struct.derivedFromName; format="cap">"): + return visitor.visit<struct.derivedFromName; format="cap">(self) + else: + return visitor.visitChildren(self) + +>> + +AttributeDecl(d) ::= "self.<d.name> = <if(d.initValue)><d.initValue><else>None<endif>" + +/** If we don't know location of label def x, use this template */ +labelref(x) ::= "<if(!x.isLocal)>localctx.<endif><x.name>" + +/** For any action chunk, what is correctly-typed context struct ptr? */ +ctx(actionChunk) ::= "localctx" + +// used for left-recursive rules +recRuleAltPredicate(ruleName,opPrec) ::= "self.precpred(self._ctx, <opPrec>)" +recRuleSetReturnAction(src,name) ::= "$<name>=$<src>.<name>" +recRuleSetStopToken() ::= "self._ctx.stop = self._input.LT(-1)" + +recRuleAltStartAction(ruleName, ctxName, label) ::= << +localctx = <parser.name>.<ctxName>Context(self, _parentctx, _parentState) +<if(label)>localctx.<label> = _prevctx<endif> +self.pushNewRecursionContext(localctx, _startState, self.RULE_<ruleName>) +>> + +recRuleLabeledAltStartAction(ruleName, currentAltLabel, label, isListLabel) ::= << +localctx = <parser.name>.<currentAltLabel; format="cap">Context(self, <parser.name>.<ruleName; format="cap">Context(self, _parentctx, _parentState)) +<if(label)> +<if(isListLabel)> +localctx.<label>.append(_prevctx) +<else> +localctx.<label> = _prevctx +<endif> +<endif> +self.pushNewRecursionContext(localctx, _startState, self.RULE_<ruleName>) +>> + + +recRuleReplaceContext(ctxName) ::= << +localctx = <parser.name>.<ctxName>Context(self, localctx) +self._ctx = localctx +_prevctx = localctx +>> + +recRuleSetPrevCtx() ::= << +if self._parseListeners is not None: + self.triggerExitRuleEvent() +_prevctx = localctx +>> + + +LexerFile(lexerFile, lexer, namedActions) ::= << +<fileHeader(lexerFile.grammarFileName, lexerFile.ANTLRVersion)> +# encoding: utf-8 +from __future__ import print_function +from antlr4 import * +from io import StringIO + +<namedActions.header> + +<lexer> +>> + +Lexer(lexer, atn, actionFuncs, sempredFuncs, superClass) ::= << + +<atn> + +class <lexer.name>(<if(superClass)><superClass><else>Lexer<endif>): + + atn = ATNDeserializer().deserialize(serializedATN()) + + decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ] + + <rest(lexer.modes):{m| <m> = <i>}; separator="\n"> + + <lexer.tokens:{k | <k> = <lexer.tokens.(k)>}; separator="\n", wrap, anchor> + + modeNames = [ <lexer.modes:{m| u"<m>"}; separator=", ", wrap, anchor> ] + + literalNames = [ u"\<INVALID>", + <lexer.literalNames:{t | u<t>}; separator=", ", wrap, anchor> ] + + symbolicNames = [ u"\<INVALID>", + <lexer.symbolicNames:{t | u<t>}; separator=", ", wrap, anchor> ] + + ruleNames = [ <lexer.ruleNames:{r | u"<r>"}; separator=", ", wrap, anchor> ] + + grammarFileName = u"<lexer.grammarFileName>" + + def __init__(self, input=None): + super(<lexer.name>, self).__init__(input) + self.checkVersion("<lexerFile.ANTLRVersion>") + self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache()) + self._actions = None + self._predicates = None + + <namedActions.members> + + <dumpActions(lexer, "", actionFuncs, sempredFuncs)> + +>> + +SerializedATN(model) ::= << +<! only one segment, can be inlined !> + +def serializedATN(): + with StringIO() as buf: + buf.write(u"<model.serialized; wrap={")<\n> buf.write(u"}>") + return buf.getvalue() + +>> + +/** 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) ::= << +<javaTypeInitMap.(typeName)> +>> + +codeFileExtension() ::= ".py" diff --git a/tool/resources/org/antlr/v4/tool/templates/codegen/Python3/Python3.stg b/tool/resources/org/antlr/v4/tool/templates/codegen/Python3/Python3.stg new file mode 100644 index 0000000..4ba1e38 --- /dev/null +++ b/tool/resources/org/antlr/v4/tool/templates/codegen/Python3/Python3.stg @@ -0,0 +1,810 @@ +/* + * [The "BSD license"] + * Copyright (c) 2012 Terence Parr + * Copyright (c) 2012 Sam Harwell + * Copyright (c) 2014 Eric Vergnaud + * 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. + */ + +/** ANTLR tool checks output templates are compatible with tool code generation. + * For now, a simple string match used on x.y of x.y.z scheme. + * Must match Tool.VERSION during load to templates. + * + * REQUIRED. + */ + +pythonTypeInitMap ::= [ + "bool":"False", + "int":"0", + "float":"0.0", + "str":"", + default:"None" // anything other than a primitive type is an object +] + +// args must be <object-model-object>, <fields-resulting-in-STs> + +ParserFile(file, parser, namedActions) ::= << +<fileHeader(file.grammarFileName, file.ANTLRVersion)> +# encoding: utf-8 +from antlr4 import * +from io import StringIO + +<namedActions.header> +<parser> + +>> + +ListenerFile(file, header) ::= << +<fileHeader(file.grammarFileName, file.ANTLRVersion)> +from antlr4 import * +if __name__ is not None and "." in __name__: + from .<file.parserName> import <file.parserName> +else: + from <file.parserName> import <file.parserName> +<header> + +# This class defines a complete listener for a parse tree produced by <file.parserName>. +class <file.grammarName>Listener(ParseTreeListener): + + <file.listenerNames:{lname | +# Enter a parse tree produced by <file.parserName>#<lname>. +def enter<lname; format="cap">(self, ctx:<file.parserName>.<lname; format="cap">Context): + pass + +# Exit a parse tree produced by <file.parserName>#<lname>. +def exit<lname; format="cap">(self, ctx:<file.parserName>.<lname; format="cap">Context): + pass + +}; separator="\n"> + +>> + + +VisitorFile(file, header) ::= << +<fileHeader(file.grammarFileName, file.ANTLRVersion)> +from antlr4 import * +if __name__ is not None and "." in __name__: + from .<file.parserName> import <file.parserName> +else: + from <file.parserName> import <file.parserName> +<header> + +# This class defines a complete generic visitor for a parse tree produced by <file.parserName>. + +class <file.grammarName>Visitor(ParseTreeVisitor): + + <file.visitorNames:{lname | +# Visit a parse tree produced by <file.parserName>#<lname>. +def visit<lname; format="cap">(self, ctx:<file.parserName>.<lname; format="cap">Context): + return self.visitChildren(ctx) + +}; separator="\n"> + +del <file.parserName> +>> + + +fileHeader(grammarFileName, ANTLRVersion) ::= << +# Generated from <grammarFileName> by ANTLR <ANTLRVersion> +>> + +Parser(parser, funcs, atn, sempredFuncs, superClass) ::= << +<Parser_(ctor="parser_ctor", ...)> +>> + +Parser_(parser, funcs, atn, sempredFuncs, ctor, superClass) ::= << +<if(superClass)> +from .<superClass> import <superClass> + +<endif> +<atn> + +class <parser.name> ( <if(superClass)><superClass><else>Parser<endif> ): + + grammarFileName = "<parser.grammarFileName>" + + atn = ATNDeserializer().deserialize(serializedATN()) + + decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ] + + sharedContextCache = PredictionContextCache() + + literalNames = [ <parser.literalNames:{t | <t>}; null="\"\<INVALID>\"", separator=", ", wrap, anchor> ] + + symbolicNames = [ <parser.symbolicNames:{t | <t>}; null="\"\<INVALID>\"", separator=", ", wrap, anchor> ] + + <parser.rules:{r | RULE_<r.name> = <r.index>}; separator="\n", wrap, anchor> + + ruleNames = [ <parser.ruleNames:{r | "<r>"}; separator=", ", wrap, anchor> ] + + EOF = <TokenLabelType()>.EOF + <if(parser.tokens)> + <parser.tokens:{k | <k>=<parser.tokens.(k)>}; separator="\n", wrap, anchor> + <endif> + + <parser:(ctor)()> + + <namedActions.members> + + <funcs; separator="\n"> + + +<if(sempredFuncs)> + def sempred(self, localctx:RuleContext, ruleIndex:int, predIndex:int): + if self._predicates == None: + self._predicates = dict() +<parser.sempredFuncs.values:{f | + self._predicates[<f.ruleIndex>] = self.<f.name>_sempred}; separator="\n "> + pred = self._predicates.get(ruleIndex, None) + if pred is None: + raise Exception("No predicate with index:" + str(ruleIndex)) + else: + return pred(localctx, predIndex) + + <sempredFuncs.values; separator="\n"> +<endif> + + + +>> + +dumpActions(recog, argFuncs, actionFuncs, sempredFuncs) ::= << +<if(actionFuncs)> +def action(self, localctx:RuleContext, ruleIndex:int, actionIndex:int): + if self._actions is None: + actions = dict() +<recog.actionFuncs.values:{f| + actions[<f.ruleIndex>] = self.<f.name>_action }; separator="\n"> + self._actions = actions + action = self._actions.get(ruleIndex, None) + if action is not None: + action(localctx, actionIndex) + else: + raise Exception("No registered action for:" + str(ruleIndex)) + +<actionFuncs.values; separator="\n"> + +<endif> +<if(sempredFuncs)> +def sempred(self, localctx:RuleContext, ruleIndex:int, predIndex:int): + if self._predicates is None: + preds = dict() +<recog.sempredFuncs.values:{f| + preds[<f.ruleIndex>] = self.<f.name>_sempred}; separator="\n"> + self._predicates = preds + pred = self._predicates.get(ruleIndex, None) + if pred is not None: + return pred(localctx, predIndex) + else: + raise Exception("No registered predicate for:" + str(ruleIndex)) + +<sempredFuncs.values; separator="\n"> +<endif> +>> + +parser_ctor(p) ::= << +def __init__(self, input:TokenStream): + super().__init__(input) + self.checkVersion("<file.ANTLRVersion>") + self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache) + self._predicates = None + +>> + +/* This generates a private method since the actionIndex is generated, making an + * overriding implementation impossible to maintain. + */ +RuleActionFunction(r, actions) ::= << + +def <r.name>_action(self, localctx:<r.ctxType> , actionIndex:int): +<actions:{index| +<if(first(actions))> + if actionIndex == <index>: + <actions.(index)> +<elseif(rest(actions))> + elif actionIndex == <index>: + <actions.(index)> +<endif> }; separator="\n"> +>> + +/* This generates a private method since the predIndex is generated, making an + * overriding implementation impossible to maintain. + */ +RuleSempredFunction(r, actions) ::= << +def <r.name>_sempred(self, localctx:<r.ctxType>, predIndex:int): + <actions:{index| +<if(first(actions))> + if predIndex == <index>: + return <actions.(index)> +<elseif(rest(actions))> + elif predIndex == <index>: + return <actions.(index)> +<endif> }; separator="\n"> + +>> + +RuleFunction(currentRule,args,code,locals,ruleCtx,altLabelCtxs,namedActions,finallyAction,postamble,exceptions) ::= << + +<ruleCtx> + +<altLabelCtxs:{l | <altLabelCtxs.(l)>}; separator="\n"> + +def <currentRule.name>(self<currentRule.args:{a | , <a.name><if(a.type)>:<a.type><endif>}>): + + localctx = <parser.name>.<currentRule.ctxType>(self, self._ctx, self.state<currentRule.args:{a | , <a.name>}>) + self.enterRule(localctx, <currentRule.startState>, self.RULE_<currentRule.name>) + <namedActions.init> + <locals; separator="\n"> + try: + <code> + <postamble; separator="\n"> + <namedActions.after> + <if(exceptions)> + <exceptions; separator="\n"> + <else> + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + <endif> + finally: + <finallyAction> + self.exitRule() + return localctx + +>> + +LeftRecursiveRuleFunction(currentRule,args,code,locals,ruleCtx,altLabelCtxs, + namedActions,finallyAction,postamble) ::= +<< + +<ruleCtx> +<altLabelCtxs:{l | <altLabelCtxs.(l)>}; separator="\n"> + +def <currentRule.name>(self, _p:int=0<if(currentRule.args)>, <args:{a | , <a>}><endif>): + _parentctx = self._ctx + _parentState = self.state + localctx = <parser.name>.<currentRule.ctxType>(self, self._ctx, _parentState<args:{a | , <a.name>}>) + _prevctx = localctx + _startState = <currentRule.startState> + self.enterRecursionRule(localctx, <currentRule.startState>, self.RULE_<currentRule.name>, _p) + <namedActions.init> + <locals; separator="\n"> + try: + <code> + <postamble; separator="\n"> + <namedActions.after> + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + <finallyAction> + self.unrollRecursionContexts(_parentctx) + return localctx + +>> + +CodeBlockForOuterMostAlt(currentOuterMostAltCodeBlock, locals, preamble, ops) ::= << +<if(currentOuterMostAltCodeBlock.altLabel)>localctx = <parser.name>.<currentOuterMostAltCodeBlock.altLabel; format="cap">Context(self, localctx)<endif> +self.enterOuterAlt(localctx, <currentOuterMostAltCodeBlock.alt.altNum>) +<CodeBlockForAlt(currentAltCodeBlock=currentOuterMostAltCodeBlock, ...)> +>> + +CodeBlockForAlt(currentAltCodeBlock, locals, preamble, ops) ::= << +<locals; separator="\n"> +<preamble; separator="\n"> +<ops; separator="\n"> +>> + +LL1AltBlock(choice, preamble, alts, error) ::= << +self.state = <choice.stateNumber> +<!_errHandler.sync(this);!> +<if(choice.label)><labelref(choice.label)> = _input.LT(1)<endif> +<preamble; separator="\n"> +token = self._input.LA(1) +<choice.altLook,alts:{look,alt| <cases(ttypes=look)> + <alt> + }; separator="\nel"> +else: + <error> + +>> + +LL1OptionalBlock(choice, alts, error) ::= << +self.state = <choice.stateNumber> +<!_errHandler.sync(this);!> +token = self._input.LA(1) +<choice.altLook,alts:{look,alt| <cases(ttypes=look)> + <alt> + pass}; separator="\nel"> +else: + <error> +>> + +LL1OptionalBlockSingleAlt(choice, expr, alts, preamble, error, followExpr) ::= << +self.state = <choice.stateNumber> +<!_errHandler.sync(this);!> +<preamble; separator="\n"> +if <expr>: + <alts; separator="\n"> + +<!else if ( !(<followExpr>) ) <error>!> +>> + + +LL1StarBlockSingleAlt(choice, loopExpr, alts, preamble, iteration) ::= << +self.state = <choice.stateNumber> +self._errHandler.sync(self) +<preamble; separator="\n"> +while <loopExpr>: + <alts; separator="\n"> + self.state = <choice.loopBackStateNumber> + self._errHandler.sync(self) + <iteration> + +>> + +LL1PlusBlockSingleAlt(choice, loopExpr, alts, preamble, iteration) ::= << +self.state = <choice.blockStartStateNumber> <! alt block decision !> +self._errHandler.sync(self) +<preamble; separator="\n"> +while True: + <alts; separator="\n"> + self.state = <choice.stateNumber> <! loopback/exit decision !> + self._errHandler.sync(self) + <iteration> + if not (<loopExpr>): + break + +>> + +// LL(*) stuff + +AltBlock(choice, preamble, alts, error) ::= << +self.state = <choice.stateNumber> +<!_errHandler.sync(this);!> +<if(choice.label)><labelref(choice.label)> = _input.LT(1)<endif> +<preamble; separator="\n"> +la_ = self._interp.adaptivePredict(self._input,<choice.decision>,self._ctx) +<alts:{alt | +if la_ == <i>: + <alt> + pass +}; separator="\nel"> + +>> + +OptionalBlock(choice, alts, error) ::= << +self.state = <choice.stateNumber> +<!_errHandler.sync(this);!> +la_ = self._interp.adaptivePredict(self._input,<choice.decision>,self._ctx) +<alts:{alt | +if la_ == <i><if(!choice.ast.greedy)>+1<endif>: + <alt> +}; separator="\nel"> + +>> + +StarBlock(choice, alts, sync, iteration) ::= << +self.state = <choice.stateNumber> +self._errHandler.sync(self) +_alt = self._interp.adaptivePredict(self._input,<choice.decision>,self._ctx) +while _alt!=<choice.exitAlt> and _alt!=ATN.INVALID_ALT_NUMBER: + if _alt==1<if(!choice.ast.greedy)>+1<endif>: + <iteration> + <alts> <! should only be one !> + self.state = <choice.loopBackStateNumber> + self._errHandler.sync(self) + _alt = self._interp.adaptivePredict(self._input,<choice.decision>,self._ctx) + +>> + +PlusBlock(choice, alts, error) ::= << +self.state = <choice.blockStartStateNumber> <! alt block decision !> +self._errHandler.sync(self) +_alt = 1<if(!choice.ast.greedy)>+1<endif> +while _alt!=<choice.exitAlt> and _alt!=ATN.INVALID_ALT_NUMBER: + <alts:{alt| +if _alt == <i><if(!choice.ast.greedy)>+1<endif>: + <alt> +}; separator="\nel"> + else: + <error> + self.state = <choice.loopBackStateNumber> <! loopback/exit decision !> + self._errHandler.sync(self) + _alt = self._interp.adaptivePredict(self._input,<choice.decision>,self._ctx) + +>> + +Sync(s) ::= "sync(<s.expecting.name>)" + +ThrowNoViableAlt(t) ::= "raise NoViableAltException(self)" + +TestSetInline(s) ::= << +<s.bitsets:{bits | <if(rest(rest(bits.ttypes)))><bitsetBitfieldComparison(s, bits)><else><bitsetInlineComparison(s, bits)><endif>}; separator=" or "> +>> + +// Java language spec 15.19 - shift operators mask operands rather than overflow to 0... need range test +testShiftInRange(shiftAmount) ::= << +((<shiftAmount>) & ~0x3f) == 0 +>> + +// produces smaller bytecode only when bits.ttypes contains more than two items +bitsetBitfieldComparison(s, bits) ::= <% +(<testShiftInRange({<offsetShiftVar(s.varName, bits.shift)>})> and ((1 \<\< <offsetShiftVar(s.varName, bits.shift)>) & (<bits.ttypes:{ttype | (1 \<\< <offsetShiftType(ttype, bits.shift)>)}; separator=" | ">)) != 0) +%> + +isZero ::= [ +"0":true, +default:false +] + +offsetShiftVar(shiftAmount, offset) ::= <% +<if(!isZero.(offset))>(<shiftAmount> - <offset>)<else><shiftAmount><endif> +%> + +offsetShiftType(shiftAmount, offset) ::= <% +<if(!isZero.(offset))>(<parser.name>.<shiftAmount> - <offset>)<else><parser.name>.<shiftAmount><endif> +%> + +// produces more efficient bytecode when bits.ttypes contains at most two items +bitsetInlineComparison(s, bits) ::= <% +<bits.ttypes:{ttype | <s.varName>==<parser.name>.<ttype>}; separator=" or "> +%> + +cases(ttypes) ::= << +if token in [<ttypes:{t | <parser.name>.<t>}; separator=", ">]: +>> + +InvokeRule(r, argExprsChunks) ::= << +self.state = <r.stateNumber> +<if(r.labels)><r.labels:{l | <labelref(l)> = }><endif>self.<r.name>(<if(r.ast.options.p)><r.ast.options.p><if(argExprsChunks)>,<endif><endif><argExprsChunks>) +>> + +MatchToken(m) ::= << +self.state = <m.stateNumber> +<if(m.labels)><m.labels:{l | <labelref(l)> = }><endif>self.match(<parser.name>.<m.name>) +>> + +MatchSet(m, expr, capture) ::= "<CommonSetStuff(m, expr, capture, false)>" + +MatchNotSet(m, expr, capture) ::= "<CommonSetStuff(m, expr, capture, true)>" + +CommonSetStuff(m, expr, capture, invert) ::= << +self.state = <m.stateNumber> +<if(m.labels)><m.labels:{l | <labelref(l)> = }>self._input.LT(1)<endif> +<capture> +<if(invert)>if <m.varName> \<= 0 or <expr><else>if not(<expr>)<endif>: +<if(m.labels)><m.labels:{l | <labelref(l)> = }><else> <endif>self._errHandler.recoverInline(self) +else: + self.consume() +>> + +Wildcard(w) ::= << +self.state = <w.stateNumber> +<if(w.labels)><w.labels:{l | <labelref(l)> = }><endif>self.matchWildcard() +>> + +// ACTION STUFF + +Action(a, foo, chunks) ::= "<chunks>" + +ArgAction(a, chunks) ::= "<chunks>" + +SemPred(p, chunks, failChunks) ::= << +self.state = <p.stateNumber> +if not <chunks>: + from antlr4.error.Errors import FailedPredicateException + raise FailedPredicateException(self, <p.predicate><if(failChunks)>, <failChunks><elseif(p.msg)>, <p.msg><endif>) +>> + +ExceptionClause(e, catchArg, catchAction) ::= << +catch (<catchArg>) { + <catchAction> +} +>> + +// lexer actions are not associated with model objects + +LexerSkipCommand() ::= "skip()" +LexerMoreCommand() ::= "more()" +LexerPopModeCommand() ::= "popMode()" + +LexerTypeCommand(arg) ::= "_type = <arg>" +LexerChannelCommand(arg) ::= "_channel = <arg>" +LexerModeCommand(arg) ::= "_mode = <arg>" +LexerPushModeCommand(arg) ::= "pushMode(<arg>)" + +ActionText(t) ::= "<t.text>" +ActionTemplate(t) ::= "<t.st>" +ArgRef(a) ::= "localctx.<a.name>" +LocalRef(a) ::= "localctx.<a.name>" +RetValueRef(a) ::= "localctx.<a.name>" +QRetValueRef(a) ::= "<ctx(a)>.<a.dict>.<a.name>" +/** How to translate $tokenLabel */ +TokenRef(t) ::= "<ctx(t)>.<t.name>" +LabelRef(t) ::= "<ctx(t)>.<t.name>" +ListLabelRef(t) ::= "<ctx(t)>.<ListLabelName(t.name)>" +SetAttr(s,rhsChunks) ::= "<ctx(s)>.<s.name> = <rhsChunks>" + +TokenLabelType() ::= "<file.TokenLabelType; null={Token}>" +InputSymbolType() ::= "<file.InputSymbolType; null={Token}>" + +TokenPropertyRef_text(t) ::= "(None if <ctx(t)>.<t.label> is None else <ctx(t)>.<t.label>.text)" +TokenPropertyRef_type(t) ::= "(0 if <ctx(t)>.<t.label> is None else <ctx(t)>.<t.label>.type()" +TokenPropertyRef_line(t) ::= "(0 if <ctx(t)>.<t.label> is None else <ctx(t)>.<t.label>.line)" +TokenPropertyRef_pos(t) ::= "(0 if <ctx(t)>.<t.label> is None else <ctx(t)>.<t.label>.column)" +TokenPropertyRef_channel(t) ::= "(0 if (<ctx(t)>.<t.label> is None else <ctx(t)>.<t.label>.channel)" +TokenPropertyRef_index(t) ::= "(0 if <ctx(t)>.<t.label> is None else <ctx(t)>.<t.label>.tokenIndex)" +TokenPropertyRef_int(t) ::= "(0 if <ctx(t)>.<t.label> is None else int(<ctx(t)>.<t.label>.text))" + +RulePropertyRef_start(r) ::= "(None if <ctx(r)>.<r.label> is None else <ctx(r)>.<r.label>.start)" +RulePropertyRef_stop(r) ::= "(None if <ctx(r)>.<r.label> is None else <ctx(r)>.<r.label>.stop)" +RulePropertyRef_text(r) ::= "(None if <ctx(r)>.<r.label> is None else self._input.getText((<ctx(r)>.<r.label>.start,<ctx(r)>.<r.label>.stop)))" +RulePropertyRef_ctx(r) ::= "<ctx(r)>.<r.label>" +RulePropertyRef_parser(r) ::= "self" + +ThisRulePropertyRef_start(r) ::= "localctx.start" +ThisRulePropertyRef_stop(r) ::= "localctx.stop" +ThisRulePropertyRef_text(r) ::= "self._input.getText((localctx.start, self._input.LT(-1)))" +ThisRulePropertyRef_ctx(r) ::= "localctx" +ThisRulePropertyRef_parser(r) ::= "self" + +NonLocalAttrRef(s) ::= "getInvokingContext(<s.ruleIndex>).<s.name>" +SetNonLocalAttr(s, rhsChunks) ::= "getInvokingContext(<s.ruleIndex>).<s.name> = <rhsChunks>" + +AddToLabelList(a) ::= "<ctx(a.label)>.<a.listName>.append(<labelref(a.label)>)" + +TokenDecl(t) ::= "self.<t.name> = None # <TokenLabelType()>" +TokenTypeDecl(t) ::= "self.<t.name> = 0 # <TokenLabelType()> type" +TokenListDecl(t) ::= "self.<t.name> = list() # of <TokenLabelType()>s" +RuleContextDecl(r) ::= "self.<r.name> = None # <r.ctxName>" +RuleContextListDecl(rdecl) ::= "self.<rdecl.name> = list() # of <rdecl.ctxName>s" + +ContextTokenGetterDecl(t) ::= << +def <t.name>(self): + return self.getToken(<parser.name>.<t.name>, 0) +>> + +// should never be called +ContextTokenListGetterDecl(t) ::= << +def <t.name>_list(self): + return self.getTokens(<parser.name>.<t.name>) +>> + +ContextTokenListIndexedGetterDecl(t) ::= << +def <t.name>(self, i:int=None): + if i is None: + return self.getTokens(<parser.name>.<t.name>) + else: + return self.getToken(<parser.name>.<t.name>, i) +>> + +ContextRuleGetterDecl(r) ::= << +def <r.name>(self): + return self.getTypedRuleContext(<parser.name>.<r.ctxName>,0) + +>> + +// should never be called +ContextRuleListGetterDecl(r) ::= << +def <r.name>_list(self): + return self.getTypedRuleContexts(<parser.name>.<r.ctxName>) + +>> + +ContextRuleListIndexedGetterDecl(r) ::= << +def <r.name>(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(<parser.name>.<r.ctxName>) + else: + return self.getTypedRuleContext(<parser.name>.<r.ctxName>,i) + +>> + +LexerRuleContext() ::= "RuleContext" + +/** The rule context name is the rule followed by a suffix; e.g., + * r becomes rContext. + */ +RuleContextNameSuffix() ::= "Context" + +ImplicitTokenLabel(tokenName) ::= "_<tokenName>" +ImplicitRuleLabel(ruleName) ::= "_<ruleName>" +ImplicitSetLabel(id) ::= "_tset<id>" +ListLabelName(label) ::= "<label>" + +CaptureNextToken(d) ::= "<d.varName> = self._input.LT(1)" +CaptureNextTokenType(d) ::= "<d.varName> = self._input.LA(1)" + +StructDecl(struct,ctorAttrs,attrs,getters,dispatchMethods,interfaces,extensionMembers, + superClass={ParserRuleContext}) ::= << +class <struct.name>(<superClass>): + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1<struct.ctorAttrs:{a | , <a.name><if(a.type)>:<a.type><endif>=None}>): + super().__init__(parent, invokingState) + self.parser = parser + <attrs:{a | <a>}; separator="\n"> + <struct.ctorAttrs:{a | self.<a.name> = <a.name>}; separator="\n"> + + <getters:{g | <g>}; separator="\n\n"> + + def getRuleIndex(self): + return <parser.name>.RULE_<struct.derivedFromName> + +<if(struct.provideCopyFrom)> <! don't need copy unless we have subclasses !> + def copyFrom(self, ctx:ParserRuleContext): + super().copyFrom(ctx) + <struct.attrs:{a | self.<a.name> = ctx.<a.name>}; separator="\n"> + +<endif> + <dispatchMethods; separator="\n"> + <extensionMembers; separator="\n"> + +>> + +AltLabelStructDecl(struct,attrs,getters,dispatchMethods) ::= << +class <struct.name>(<currentRule.name; format="cap">Context): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a <parser.name>.<currentRule.name; format="cap">Context + super().__init__(parser) + <attrs:{a | <a>}; separator="\n"> + self.copyFrom(ctx) + + <getters:{g | <g>}; separator="\n"> + + <dispatchMethods; separator="\n"> + +>> + +ListenerDispatchMethod(method) ::= << +def <if(method.isEnter)>enter<else>exit<endif>Rule(self, listener:ParseTreeListener): + if hasattr( listener, "<if(method.isEnter)>enter<else>exit<endif><struct.derivedFromName; format="cap">" ): + listener.<if(method.isEnter)>enter<else>exit<endif><struct.derivedFromName; format="cap">(self) + +>> + +VisitorDispatchMethod(method) ::= << +def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visit<struct.derivedFromName; format="cap">" ): + return visitor.visit<struct.derivedFromName; format="cap">(self) + else: + return visitor.visitChildren(self) + +>> + +AttributeDecl(d) ::= "self.<d.name> = <if(d.initValue)><d.initValue><else>None<endif>" + +/** If we don't know location of label def x, use this template */ +labelref(x) ::= "<if(!x.isLocal)>localctx.<endif><x.name>" + +/** For any action chunk, what is correctly-typed context struct ptr? */ +ctx(actionChunk) ::= "localctx" + +// used for left-recursive rules +recRuleAltPredicate(ruleName,opPrec) ::= "self.precpred(self._ctx, <opPrec>)" +recRuleSetReturnAction(src,name) ::= "$<name>=$<src>.<name>" +recRuleSetStopToken() ::= "self._ctx.stop = self._input.LT(-1)" + +recRuleAltStartAction(ruleName, ctxName, label) ::= << +localctx = <parser.name>.<ctxName>Context(self, _parentctx, _parentState) +<if(label)>localctx.<label> = _prevctx<endif> +self.pushNewRecursionContext(localctx, _startState, self.RULE_<ruleName>) +>> + +recRuleLabeledAltStartAction(ruleName, currentAltLabel, label, isListLabel) ::= << +localctx = <parser.name>.<currentAltLabel; format="cap">Context(self, <parser.name>.<ruleName; format="cap">Context(self, _parentctx, _parentState)) +<if(label)> +<if(isListLabel)> +localctx.<label>.append(_prevctx) +<else> +localctx.<label> = _prevctx +<endif> +<endif> +self.pushNewRecursionContext(localctx, _startState, self.RULE_<ruleName>) +>> + +recRuleReplaceContext(ctxName) ::= << +localctx = <parser.name>.<ctxName>Context(self, localctx) +self._ctx = localctx +_prevctx = localctx +>> + +recRuleSetPrevCtx() ::= << +if self._parseListeners is not None: + self.triggerExitRuleEvent() +_prevctx = localctx +>> + + +LexerFile(lexerFile, lexer, namedActions) ::= << +<fileHeader(lexerFile.grammarFileName, lexerFile.ANTLRVersion)> +from antlr4 import * +from io import StringIO + +<namedActions.header> + +<lexer> +>> + +Lexer(lexer, atn, actionFuncs, sempredFuncs, superClass) ::= << + +<atn> + +class <lexer.name>(<if(superClass)><superClass><else>Lexer<endif>): + + atn = ATNDeserializer().deserialize(serializedATN()) + + decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ] + + <rest(lexer.modes):{m| <m> = <i>}; separator="\n"> + + <lexer.tokens:{k | <k> = <lexer.tokens.(k)>}; separator="\n", wrap, anchor> + + modeNames = [ <lexer.modes:{m| "<m>"}; separator=", ", wrap, anchor> ] + + literalNames = [ "\<INVALID>", + <lexer.literalNames:{t | <t>}; separator=", ", wrap, anchor> ] + + symbolicNames = [ "\<INVALID>", + <lexer.symbolicNames:{t | <t>}; separator=", ", wrap, anchor> ] + + ruleNames = [ <lexer.ruleNames:{r | "<r>"}; separator=", ", wrap, anchor> ] + + grammarFileName = "<lexer.grammarFileName>" + + def __init__(self, input=None): + super().__init__(input) + self.checkVersion("<lexerFile.ANTLRVersion>") + self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache()) + self._actions = None + self._predicates = None + + <namedActions.members> + + <dumpActions(lexer, "", actionFuncs, sempredFuncs)> + +>> + +SerializedATN(model) ::= << +<! only one segment, can be inlined !> + +def serializedATN(): + with StringIO() as buf: + buf.write("<model.serialized; wrap={")<\n> buf.write("}>") + return buf.getvalue() + +>> + +/** 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) ::= << +<javaTypeInitMap.(typeName)> +>> + +codeFileExtension() ::= ".py" diff --git a/tool/resources/org/antlr/v4/tool/templates/depend.stg b/tool/resources/org/antlr/v4/tool/templates/depend.stg new file mode 100644 index 0000000..dad7568 --- /dev/null +++ b/tool/resources/org/antlr/v4/tool/templates/depend.stg @@ -0,0 +1,41 @@ +/* + * [The "BSD license"] + * Copyright (c) 2012 Terence Parr + * Copyright (c) 2012 Sam Harwell + * 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. + */ + +/** templates used to generate make-compatible dependencies */ + +/** Generate "f : x, y, z" dependencies for input + * dependencies and generated files. in and out + * are File objects. For example, you can say + * <f.canonicalPath> + */ +dependencies(grammarFileName,in,out) ::= << +<if(in)><grammarFileName>: <in; separator=", "><endif> +<out:{f | <f> : <grammarFileName>}; separator="\n"> +>> diff --git a/tool/resources/org/antlr/v4/tool/templates/dot/graphs.stg b/tool/resources/org/antlr/v4/tool/templates/dot/graphs.stg new file mode 100644 index 0000000..cf071f1 --- /dev/null +++ b/tool/resources/org/antlr/v4/tool/templates/dot/graphs.stg @@ -0,0 +1,90 @@ +/* + * [The "BSD license"] + * Copyright (c) 2012 Terence Parr + * Copyright (c) 2012 Sam Harwell + * 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. + */ + +atn(startState, states, edges, rankdir, decisionRanks, useBox) ::= << +digraph ATN { +rankdir=LR; +<decisionRanks; separator="\n"> +<states; separator="\n"> +<edges; separator="\n"> +} +>> + +dfa(name, startState, states, edges, rankdir, decisionRanks, useBox) ::= << +digraph <name> { +<if(rankdir)>rankdir=<rankdir>;<endif> +<decisionRanks; separator="\n"> +<states; separator="\n"> +<edges; separator="\n"> +} +>> + +decision-rank(states) ::= << +{rank=same; rankdir=TB; <states:{s | s<s>}; separator="; ">} +>> + +edge(src,target,label,arrowhead,transitionIndex) ::= << +<src><if(transitionIndex)>:p<transitionIndex><endif> -> <target> [fontsize=11, fontname="Courier", arrowsize=.7, label = "<label>"<if(arrowhead)>, arrowhead = <arrowhead><endif>]; +>> + +action-edge(src,target,label,arrowhead,transitionIndex) ::= << +<src><if(transitionIndex)>:p<transitionIndex><endif> -> <target> [fontsize=11, fontname="Courier", arrowsize=.7, label = "<label>"<if(arrowhead)>, arrowhead = <arrowhead><endif>]; +>> + +epsilon-edge(src,label,target,arrowhead,transitionIndex,loopback=false) ::= << +<src><if(transitionIndex)>:p<transitionIndex><endif> -> <target> [fontname="Times-Italic", label="ε"<if(loopback)>, style="dashed"<endif>]; +>> + +state(state, label, name, transitions) ::= <% +<name>[fontsize=11, + label=" + <! rest(transition) tests for decision states: these nodes have a non-empty set of transitions after the first one. !> + <if(rest(transitions))> + { + <! Label on the left side of the record node. !> + <label> + | + <! Named ports in order on right side of record node, no display text. !> + {<transitions:{t|\<p<i0>>}; separator="|">}} + <else> + <label> + <endif> + " + <if(rest(transitions))> + , shape=record, fixedsize=false + <else> + , shape=circle, fixedsize=true, width=.55 + <endif> + , peripheries=1]; +%> + +stopstate(name,label,actionIndex,useBox) ::= << +<name>[fontsize=11, label="<label><if(actionIndex)>,\naction:<actionIndex><endif>", <if(useBox)>shape=polygon,sides=4,peripheries=2,fixedsize=false<else>shape=doublecircle, fixedsize=true, width=.6<endif>]; +>> diff --git a/tool/resources/org/antlr/v4/tool/templates/messages/formats/antlr.stg b/tool/resources/org/antlr/v4/tool/templates/messages/formats/antlr.stg new file mode 100644 index 0000000..fb996f5 --- /dev/null +++ b/tool/resources/org/antlr/v4/tool/templates/messages/formats/antlr.stg @@ -0,0 +1,39 @@ +/* + [The "BSD licence"] + Copyright (c) 2006 Kay Roepke + 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. +*/ +/* + This file contains the actual layout of the messages emitted by ANTLR. + This file contains the default format ANTLR uses. +*/ + +location(file, line, column) ::= "<file>:<line>:<column>:" + +message(id, text) ::= "(<id>) <text>" + +report(location, message, type) ::= "<type>(<message.id>): <location> <message.text>" + +wantsSingleLineMessage() ::= "false" diff --git a/tool/resources/org/antlr/v4/tool/templates/messages/formats/gnu.stg b/tool/resources/org/antlr/v4/tool/templates/messages/formats/gnu.stg new file mode 100644 index 0000000..f243ab7 --- /dev/null +++ b/tool/resources/org/antlr/v4/tool/templates/messages/formats/gnu.stg @@ -0,0 +1,40 @@ +/* + [The "BSD licence"] + Copyright (c) 2006 Kay Roepke + 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. +*/ +/* +This file contains the actual layout of the messages emitted by ANTLR. + The text itself is coming out of the languages/*stg files, according to the chosen locale. + This file contains the format that mimicks GCC output. +*/ + +location(file, line, column) ::= "<file>:<line>:" + +message(id, text) ::= "<text> (<id>)" + +report(location, message, type) ::= "<location> <type>: <message>" + +wantsSingleLineMessage() ::= "true" diff --git a/tool/resources/org/antlr/v4/tool/templates/messages/formats/vs2005.stg b/tool/resources/org/antlr/v4/tool/templates/messages/formats/vs2005.stg new file mode 100644 index 0000000..819e8a8 --- /dev/null +++ b/tool/resources/org/antlr/v4/tool/templates/messages/formats/vs2005.stg @@ -0,0 +1,40 @@ +/* + [The "BSD licence"] + Copyright (c) 2006 Kay Roepke + 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. +*/ +/* + This file contains the actual layout of the messages emitted by ANTLR. + The text itself is coming out of the languages/*stg files, according to the chosen locale. + This file contains the default format ANTLR uses. +*/ + +location(file, line, column) ::= "<file>(<line>,<column>)" + +message(id, text) ::= "error <id> : <text>" + +report(location, message, type) ::= "<location> : <type> <message.id> : <message.text>" + +wantsSingleLineMessage() ::= "true" |