forked from jasder/antlr
simplified label computation
[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 6839]
This commit is contained in:
parent
b0ca11f46b
commit
27d9f25ec2
|
@ -70,7 +70,7 @@ processOneChar:
|
||||||
ip = t.addr;
|
ip = t.addr;
|
||||||
NFAStack context = t.context;
|
NFAStack context = t.context;
|
||||||
int alt = t.alt;
|
int alt = t.alt;
|
||||||
System.out.println("input["+input.index()+"]=="+(char)c+" closure="+closure+", i="+i+", reach="+ reach);
|
//System.out.println("input["+input.index()+"]=="+(char)c+" closure="+closure+", i="+i+", reach="+ reach);
|
||||||
trace(ip);
|
trace(ip);
|
||||||
short opcode = code[ip];
|
short opcode = code[ip];
|
||||||
ip++; // move to next instruction or first byte of operand
|
ip++; // move to next instruction or first byte of operand
|
||||||
|
@ -284,7 +284,7 @@ processOneChar:
|
||||||
processOneChar:
|
processOneChar:
|
||||||
while ( i<closure.size() ) {
|
while ( i<closure.size() ) {
|
||||||
//for (int i=0; i<closure.size(); i++) {
|
//for (int i=0; i<closure.size(); i++) {
|
||||||
System.out.println("input["+input.index()+"]=="+(char)c+" closure="+closure+", i="+i+", reach="+ reach);
|
//System.out.println("input["+input.index()+"]=="+(char)c+" closure="+closure+", i="+i+", reach="+ reach);
|
||||||
ip = closure.get(i);
|
ip = closure.get(i);
|
||||||
trace(ip);
|
trace(ip);
|
||||||
short opcode = code[ip];
|
short opcode = code[ip];
|
||||||
|
|
|
@ -5,6 +5,7 @@ import org.antlr.runtime.Token;
|
||||||
import org.antlr.runtime.tree.CommonTreeNodeStream;
|
import org.antlr.runtime.tree.CommonTreeNodeStream;
|
||||||
import org.antlr.runtime.tree.TreeNodeStream;
|
import org.antlr.runtime.tree.TreeNodeStream;
|
||||||
import org.antlr.v4.codegen.nfa.*;
|
import org.antlr.v4.codegen.nfa.*;
|
||||||
|
import org.antlr.v4.misc.DoubleKeyMap;
|
||||||
import org.antlr.v4.parse.ANTLRParser;
|
import org.antlr.v4.parse.ANTLRParser;
|
||||||
import org.antlr.v4.parse.GrammarASTAdaptor;
|
import org.antlr.v4.parse.GrammarASTAdaptor;
|
||||||
import org.antlr.v4.runtime.nfa.Bytecode;
|
import org.antlr.v4.runtime.nfa.Bytecode;
|
||||||
|
@ -27,13 +28,21 @@ public class NFABytecodeGenerator extends TreeParser {
|
||||||
Map<String, Integer> ruleToAddr = new HashMap<String, Integer>();
|
Map<String, Integer> ruleToAddr = new HashMap<String, Integer>();
|
||||||
int[] tokenTypeToAddr;
|
int[] tokenTypeToAddr;
|
||||||
|
|
||||||
Map<Rule, Map<String, Integer>> ruleLabels = new HashMap<Rule, Map<String, Integer>>();
|
DoubleKeyMap<Rule, String, Integer> ruleLabels = new DoubleKeyMap<Rule, String, Integer>();
|
||||||
Map<Rule, Map<Token, Integer>> ruleActions = new HashMap<Rule, Map<Token, Integer>>();
|
DoubleKeyMap<Rule, Token, Integer> ruleActions = new DoubleKeyMap<Rule, Token, Integer>();
|
||||||
Map<Rule, Map<Token, Integer>> ruleSempreds = new HashMap<Rule, Map<Token, Integer>>();
|
DoubleKeyMap<Rule, Token, Integer> ruleSempreds = new DoubleKeyMap<Rule, Token, Integer>();
|
||||||
|
|
||||||
public Rule currentRule;
|
public Rule currentRule;
|
||||||
|
|
||||||
public int labelIndex = 0;
|
public int labelIndex = 0; // first time we ask for labels we index
|
||||||
|
|
||||||
|
// public abstract class LabelMaker<Key,Label> {
|
||||||
|
// Map<Key,Label> labels = new HashMap<Key,Label>();
|
||||||
|
// public LabelMaker(Collection<Key> keys) {
|
||||||
|
// for (Key k : keys) labels.put(k, computeLabel(k));
|
||||||
|
// }
|
||||||
|
// public abstract Label computeLabel(Key k);
|
||||||
|
// }
|
||||||
|
|
||||||
public NFABytecodeGenerator(TreeNodeStream input, RecognizerSharedState state) {
|
public NFABytecodeGenerator(TreeNodeStream input, RecognizerSharedState state) {
|
||||||
super(input, state);
|
super(input, state);
|
||||||
|
@ -49,36 +58,22 @@ public class NFABytecodeGenerator extends TreeParser {
|
||||||
|
|
||||||
// indexed from 0 per rule
|
// indexed from 0 per rule
|
||||||
public int getActionIndex(Rule r, Token actionToken) {
|
public int getActionIndex(Rule r, Token actionToken) {
|
||||||
Map<Token, Integer> actions = ruleActions.get(r);
|
Integer I = ruleActions.get(r, actionToken);
|
||||||
if ( actions==null ) {
|
if ( I!=null ) return I; // already got its label
|
||||||
actions = new HashMap<Token, Integer>();
|
Map<Token, Integer> labels = ruleActions.get(r);
|
||||||
ruleActions.put(r, actions);
|
int i = labels.size();
|
||||||
}
|
ruleActions.put(r, actionToken, i);
|
||||||
if ( actions.get(actionToken)!=null ) {
|
return i;
|
||||||
return actions.get(actionToken);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int i = actions.size();
|
|
||||||
actions.put(actionToken, i);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// indexed from 0 per rule
|
// indexed from 0 per rule
|
||||||
public int getSempredIndex(Rule r, Token actionToken) {
|
public int getSempredIndex(Rule r, Token actionToken) {
|
||||||
Map<Token, Integer> actions = ruleSempreds.get(r);
|
Integer I = ruleSempreds.get(r, actionToken);
|
||||||
if ( actions==null ) {
|
if ( I!=null ) return I; // already got its label
|
||||||
actions = new HashMap<Token, Integer>();
|
Map<Token, Integer> labels = ruleSempreds.get(r);
|
||||||
ruleSempreds.put(r, actions);
|
int i = labels.size();
|
||||||
}
|
ruleSempreds.put(r, actionToken, i);
|
||||||
if ( actions.get(actionToken)!=null ) {
|
return i;
|
||||||
return actions.get(actionToken);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int i = actions.size();
|
|
||||||
actions.put(actionToken, i);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** labels in all rules share single label space
|
/** labels in all rules share single label space
|
||||||
|
@ -86,18 +81,11 @@ public class NFABytecodeGenerator extends TreeParser {
|
||||||
* to an index in an action.
|
* to an index in an action.
|
||||||
*/
|
*/
|
||||||
public int getLabelIndex(Rule r, String labelName) {
|
public int getLabelIndex(Rule r, String labelName) {
|
||||||
Map<String, Integer> labels = ruleLabels.get(r);
|
Integer I = ruleLabels.get(r, labelName);
|
||||||
if ( labels==null ) {
|
if ( I!=null ) return I; // already got its label
|
||||||
labels = new HashMap<String, Integer>();
|
int i = labelIndex++;
|
||||||
ruleLabels.put(r, labels);
|
ruleLabels.put(r, labelName, i);
|
||||||
}
|
return i;
|
||||||
if ( labels.get(labelName)!=null ) {
|
|
||||||
return labels.get(labelName);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
labels.put(labelName, labelIndex);
|
|
||||||
return labelIndex++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void emitString(Token t) {
|
public void emitString(Token t) {
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
package org.antlr.v4.misc;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/** Sometimes we need to map a key to a value but key is two pieces of data.
|
||||||
|
* This nested hash table saves creating a single key each time we access
|
||||||
|
* map; avoids mem creation.
|
||||||
|
*/
|
||||||
|
public class DoubleKeyMap<Key1, Key2, Value> {
|
||||||
|
Map<Key1, Map<Key2, Value>> data = new HashMap<Key1, Map<Key2, Value>>();
|
||||||
|
|
||||||
|
public Value put(Key1 k1, Key2 k2, Value v) {
|
||||||
|
Map<Key2, Value> data2 = data.get(k1);
|
||||||
|
Value prev = null;
|
||||||
|
if ( data2==null ) {
|
||||||
|
data2 = new HashMap<Key2, Value>();
|
||||||
|
data.put(k1, data2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
prev = data2.get(k2);
|
||||||
|
}
|
||||||
|
data2.put(k2, v);
|
||||||
|
return prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Value get(Key1 k1, Key2 k2) {
|
||||||
|
Map<Key2, Value> data2 = data.get(k1);
|
||||||
|
if ( data2==null ) {
|
||||||
|
data2 = new HashMap<Key2, Value>();
|
||||||
|
data.put(k1, data2);
|
||||||
|
}
|
||||||
|
return data2.get(k2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<Key2, Value> get(Key1 k1) { return data.get(k1); }
|
||||||
|
}
|
Loading…
Reference in New Issue