simplified label computation

[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 6839]
This commit is contained in:
parrt 2010-05-04 12:04:49 -08:00
parent b0ca11f46b
commit 27d9f25ec2
3 changed files with 69 additions and 44 deletions

View File

@ -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];

View File

@ -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) {

View File

@ -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); }
}