more impl of get/set alt num; update doc

This commit is contained in:
parrt 2016-03-28 14:10:29 -07:00
parent fa10ca678f
commit e4a4253219
6 changed files with 71 additions and 7 deletions

View File

@ -12,6 +12,54 @@ where a value can be an identifier, a qualified identifier (for example, a.b.c),
All grammars can use the following options. In combined grammars, all options except language pertain only to the generated parser. Options may be set either within the grammar file using the options syntax (described above) or when invoking ANTLR on the command line, using the `-D` option. (see Section 15.9, [ANTLR Tool Command Line Options](tool-options.md).) The following examples demonstrate both mechanisms; note that `-D` overrides options within the grammar. All grammars can use the following options. In combined grammars, all options except language pertain only to the generated parser. Options may be set either within the grammar file using the options syntax (described above) or when invoking ANTLR on the command line, using the `-D` option. (see Section 15.9, [ANTLR Tool Command Line Options](tool-options.md).) The following examples demonstrate both mechanisms; note that `-D` overrides options within the grammar.
* `superClass`. Set the superclass of the generated parser or lexer. For combined grammars, it sets the superclass of the parser.
```
$ cat Hi.g4
grammar Hi;
a : 'hi' ;
$ antlr4 -DsuperClass=XX Hi.g4
$ grep 'public class' HiParser.java
public class HiParser extends XX {
$ grep 'public class' HiLexer.java
public class HiLexer extends Lexer {
```
* `language` Generate code in the indicated language, if ANTLR is able to do so. Otherwise, you will see an error message like this:
```
$ antlr4 -Dlanguage=C MyGrammar.g4
error(31): ANTLR cannot generate C code as of version 4.0
```
* `tokenVocab` ANTLR assigns token type numbers to the tokens as it encounters them in a file. To use different token type values, such as with a separate lexer, use this option to have ANTLR pull in the <fileextension>tokens</fileextension> file. ANTLR generates a <fileextension>tokens</fileextension> file from each grammar.
```
$ cat SomeLexer.g4
lexer grammar SomeLexer;
ID : [a-z]+ ;
$ cat R.g4
parser grammar R;
options {tokenVocab=SomeLexer;}
tokens {A,B,C} // normally, these would be token types 1, 2, 3
a : ID ;
$ antlr4 SomeLexer.g4
$ cat SomeLexer.tokens
ID=1
$ antlr4 R.g4
$ cat R.tokens
A=2
B=3
C=4
ID=1
```
* `TokenLabelType` ANTLR normally uses type <class>Token</class> when it generates variables referencing tokens. If you have passed a <class>TokenFactory</class> to your parser and lexer so that they create custom tokens, you should set this option to your specific type. This ensures that the context objects know your type for fields and method return values.
```
$ cat T2.g4
grammar T2;
options {TokenLabelType=MyToken;}
a : x=ID ;
$ antlr4 T2.g4
$ grep MyToken T2Parser.java
public MyToken x;
```
* `contextSuperClass`. Specify the super class of parse tree internal nodes. Default is `ParserRuleContext`. Should derived from ultimately `RuleContext` at minimum.
## Rule Options ## Rule Options
There are currently no valid rule-level options, but the tool still supports the following syntax for future use: There are currently no valid rule-level options, but the tool still supports the following syntax for future use:

View File

@ -34,7 +34,6 @@ import org.antlr.v4.runtime.atn.ATNDeserializationOptions;
import org.antlr.v4.runtime.atn.ATNDeserializer; import org.antlr.v4.runtime.atn.ATNDeserializer;
import org.antlr.v4.runtime.atn.ATNSimulator; import org.antlr.v4.runtime.atn.ATNSimulator;
import org.antlr.v4.runtime.atn.ATNState; import org.antlr.v4.runtime.atn.ATNState;
import org.antlr.v4.runtime.atn.AmbiguityInfo;
import org.antlr.v4.runtime.atn.ParseInfo; import org.antlr.v4.runtime.atn.ParseInfo;
import org.antlr.v4.runtime.atn.ParserATNSimulator; import org.antlr.v4.runtime.atn.ParserATNSimulator;
import org.antlr.v4.runtime.atn.PredictionMode; import org.antlr.v4.runtime.atn.PredictionMode;
@ -51,7 +50,6 @@ import org.antlr.v4.runtime.tree.pattern.ParseTreePattern;
import org.antlr.v4.runtime.tree.pattern.ParseTreePatternMatcher; import org.antlr.v4.runtime.tree.pattern.ParseTreePatternMatcher;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -649,6 +647,7 @@ public abstract class Parser extends Recognizer<Token, ParserATNSimulator> {
} }
public void enterOuterAlt(ParserRuleContext localctx, int altNum) { public void enterOuterAlt(ParserRuleContext localctx, int altNum) {
localctx.setAltNumber(altNum);
// if we have new localctx, make sure we replace existing ctx // if we have new localctx, make sure we replace existing ctx
// that is previous child of parse tree // that is previous child of parse tree
if ( _buildParseTrees && _ctx != localctx ) { if ( _buildParseTrees && _ctx != localctx ) {

View File

@ -170,13 +170,23 @@ public class RuleContext implements RuleNode {
* the outer alternative number used to match the input. Default * the outer alternative number used to match the input. Default
* implementation does not compute nor store this alt num. Create * implementation does not compute nor store this alt num. Create
* a subclass of ParserRuleContext with backing field and set * a subclass of ParserRuleContext with backing field and set
* option treeSuperClass. Then override Parser.enterOuterAlt() * option contextSuperClass.
* to set it. * to set it.
* *
* @since 4.5.3 * @since 4.5.3
*/ */
public int getAltNumber() { return ATN.INVALID_ALT_NUMBER; } public int getAltNumber() { return ATN.INVALID_ALT_NUMBER; }
/** Set the outer alternative number for this context node. Default
* implementation does nothing to avoid backing field overhead for
* trees that don't need it. Create
* a subclass of ParserRuleContext with backing field and set
* option contextSuperClass.
*
* @since 4.5.3
*/
public void setAltNumber(int altNumber) { }
@Override @Override
public ParseTree getChild(int i) { public ParseTree getChild(int i) {
return null; return null;

View File

@ -765,9 +765,8 @@ ListLabelName(label) ::= "<label>"
CaptureNextToken(d) ::= "<d.varName> = _input.LT(1);" CaptureNextToken(d) ::= "<d.varName> = _input.LT(1);"
CaptureNextTokenType(d) ::= "<d.varName> = _input.LA(1);" CaptureNextTokenType(d) ::= "<d.varName> = _input.LA(1);"
StructDecl(struct,ctorAttrs,attrs,getters,dispatchMethods,interfaces,extensionMembers, StructDecl(struct,ctorAttrs,attrs,getters,dispatchMethods,interfaces,extensionMembers) ::= <<
superClass={ParserRuleContext}) ::= << public static class <struct.name> extends <if(contextSuperClass)><contextSuperClass><else>ParserRuleContext<endif><if(interfaces)> implements <interfaces; separator=", "><endif> {
public static class <struct.name> extends <superClass><if(interfaces)> implements <interfaces; separator=", "><endif> {
<attrs:{a | public <a>;}; separator="\n"> <attrs:{a | public <a>;}; separator="\n">
<getters:{g | <g>}; separator="\n"> <getters:{g | <g>}; separator="\n">
<if(ctorAttrs)>public <struct.name>(ParserRuleContext parent, int invokingState) { super(parent, invokingState); }<endif> <if(ctorAttrs)>public <struct.name>(ParserRuleContext parent, int invokingState) { super(parent, invokingState); }<endif>

View File

@ -31,6 +31,8 @@
package org.antlr.v4.codegen.model; package org.antlr.v4.codegen.model;
import org.antlr.v4.codegen.OutputModelFactory; import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.codegen.model.chunk.ActionChunk;
import org.antlr.v4.codegen.model.chunk.ActionText;
import org.antlr.v4.tool.Grammar; import org.antlr.v4.tool.Grammar;
import org.antlr.v4.tool.ast.ActionAST; import org.antlr.v4.tool.ast.ActionAST;
@ -42,6 +44,7 @@ public class ParserFile extends OutputFile {
public String genPackage; // from -package cmd-line public String genPackage; // from -package cmd-line
@ModelElement public Parser parser; @ModelElement public Parser parser;
@ModelElement public Map<String, Action> namedActions; @ModelElement public Map<String, Action> namedActions;
@ModelElement public ActionChunk contextSuperClass;
public Boolean genListener = false; public Boolean genListener = false;
public Boolean genVisitor = false; public Boolean genVisitor = false;
public String grammarName; public String grammarName;
@ -59,5 +62,9 @@ public class ParserFile extends OutputFile {
genListener = g.tool.gen_listener; genListener = g.tool.gen_listener;
genVisitor = g.tool.gen_visitor; genVisitor = g.tool.gen_visitor;
grammarName = g.name; grammarName = g.name;
if (g.getOptionString("superClass") != null) {
contextSuperClass = new ActionText(null, g.getOptionString("superClass"));
}
} }
} }

View File

@ -101,6 +101,7 @@ public class Grammar implements AttributeResolver {
public static final Set<String> parserOptions = new HashSet<String>(); public static final Set<String> parserOptions = new HashSet<String>();
static { static {
parserOptions.add("superClass"); parserOptions.add("superClass");
parserOptions.add("contextSuperClass");
parserOptions.add("TokenLabelType"); parserOptions.add("TokenLabelType");
parserOptions.add("tokenVocab"); parserOptions.add("tokenVocab");
parserOptions.add("language"); parserOptions.add("language");