forked from jasder/antlr
got INT calls DIGIT working
[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 6830]
This commit is contained in:
parent
9dbc6a43fd
commit
f3e6d4644d
|
@ -8,40 +8,15 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
/** http://swtch.com/~rsc/regexp/regexp2.html */
|
||||
/*
|
||||
for(;;){
|
||||
switch(pc->opcode){
|
||||
case Char:
|
||||
if(*sp != pc->c)
|
||||
return 0;
|
||||
pc++;
|
||||
sp++;
|
||||
continue;
|
||||
case Match:
|
||||
return 1;
|
||||
case Jmp:
|
||||
pc = pc->x;
|
||||
continue;
|
||||
case Split:
|
||||
if(recursiveloop(pc->x, sp))
|
||||
return 1;
|
||||
pc = pc->y;
|
||||
continue;
|
||||
}
|
||||
assert(0);
|
||||
return -1;
|
||||
}
|
||||
*/
|
||||
public class NFA {
|
||||
public byte[] code;
|
||||
Map<String, Integer> ruleToAddr;
|
||||
public int[] tokenTypeToAddr;
|
||||
// 7, 29 -> rule
|
||||
// 7..28, 29..len
|
||||
|
||||
public NFA(byte[] code, Map<String, Integer> ruleToAddr) {
|
||||
public NFA(byte[] code, Map<String, Integer> ruleToAddr, int[] tokenTypeToAddr) {
|
||||
this.code = code;
|
||||
this.ruleToAddr = ruleToAddr;
|
||||
this.tokenTypeToAddr = tokenTypeToAddr;
|
||||
}
|
||||
|
||||
public int exec(CharStream input, String ruleName) {
|
||||
|
@ -310,7 +285,7 @@ processOneChar:
|
|||
case Bytecode.SAVE :
|
||||
int labelIndex = getShort(code, ip);
|
||||
ip += 2;
|
||||
addToClosure(closure, ip, alt, context); // do closure pass SAVE
|
||||
addToClosure(closure, ip, alt, context); // do closure past SAVE
|
||||
// TODO: impl
|
||||
break;
|
||||
case Bytecode.SPLIT :
|
||||
|
@ -321,6 +296,18 @@ processOneChar:
|
|||
addToClosure(closure, getShort(code, ip+i*2), alt, context);
|
||||
}
|
||||
break;
|
||||
case Bytecode.CALL :
|
||||
int target = getShort(code, ip);
|
||||
int retaddr = ip+2;
|
||||
addToClosure(closure, target, alt, new NFAStack(context, retaddr));
|
||||
break;
|
||||
case Bytecode.RET :
|
||||
if ( context != NFAStack.EMPTY ) {
|
||||
addToClosure(closure, context.returnAddr, alt, context.parent);
|
||||
}
|
||||
break;
|
||||
case Bytecode.ACCEPT :
|
||||
// if stack
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -194,24 +194,32 @@ public class NFABytecodeGenerator extends TreeParser {
|
|||
}
|
||||
|
||||
/** Given any block of alts, return list of instruction objects */
|
||||
public static List<Instr> getInstructions(GrammarAST blk, int acceptValue) {
|
||||
GrammarASTAdaptor adaptor = new GrammarASTAdaptor();
|
||||
CommonTreeNodeStream nodes = new CommonTreeNodeStream(adaptor,blk);
|
||||
NFABytecodeTriggers gen = new NFABytecodeTriggers(nodes);
|
||||
try {
|
||||
gen.block();
|
||||
gen.emit(new NFABytecodeGenerator.AcceptInstr(acceptValue));
|
||||
}
|
||||
catch (Exception e){
|
||||
e.printStackTrace(System.err);
|
||||
}
|
||||
return gen.instrs;
|
||||
}
|
||||
// public static List<Instr> getInstructions(GrammarAST blk, int acceptValue) {
|
||||
// GrammarASTAdaptor adaptor = new GrammarASTAdaptor();
|
||||
// CommonTreeNodeStream nodes = new CommonTreeNodeStream(adaptor,blk);
|
||||
// NFABytecodeTriggers gen = new NFABytecodeTriggers(nodes);
|
||||
// try {
|
||||
// gen.block();
|
||||
// gen.emit(new NFABytecodeGenerator.AcceptInstr(acceptValue));
|
||||
// }
|
||||
// catch (Exception e){
|
||||
// e.printStackTrace(System.err);
|
||||
// }
|
||||
// return gen.instrs;
|
||||
// }
|
||||
|
||||
public static byte[] getByteCode(List<Instr> instrs) {
|
||||
public static byte[] getByteCode(Map<String, Integer> ruleToAddr, List<Instr> instrs) {
|
||||
Instr last = instrs.get(instrs.size() - 1);
|
||||
int size = last.addr + last.nBytes();
|
||||
byte[] code = new byte[size];
|
||||
// resolve CALL instruction targets before generating code
|
||||
for (Instr I : instrs) {
|
||||
if ( I instanceof CallInstr ) {
|
||||
CallInstr C = (CallInstr) I;
|
||||
String ruleName = C.token.getText();
|
||||
C.target = ruleToAddr.get(ruleName);
|
||||
}
|
||||
}
|
||||
for (Instr I : instrs) {
|
||||
I.write(code);
|
||||
}
|
||||
|
@ -255,12 +263,11 @@ public class NFABytecodeGenerator extends TreeParser {
|
|||
e.printStackTrace(System.err);
|
||||
}
|
||||
}
|
||||
byte[] code = NFABytecodeGenerator.getByteCode(gen.instrs);
|
||||
byte[] code = NFABytecodeGenerator.getByteCode(ruleToAddr, gen.instrs);
|
||||
System.out.println(Bytecode.disassemble(code));
|
||||
System.out.println("rule addrs="+ruleToAddr);
|
||||
|
||||
NFA nfa = new NFA(code, ruleToAddr);
|
||||
nfa.tokenTypeToAddr = tokenTypeToAddr;
|
||||
return nfa;
|
||||
return new NFA(code, ruleToAddr, tokenTypeToAddr);
|
||||
}
|
||||
|
||||
/** Write value at index into a byte array highest to lowest byte,
|
||||
|
|
|
@ -170,7 +170,7 @@ terminal
|
|||
| STRING_LITERAL {emitString($STRING_LITERAL.token);}
|
||||
| ^(TOKEN_REF ARG_ACTION .) {emit(new CallInstr($TOKEN_REF.token));}
|
||||
| ^(TOKEN_REF .) {emit(new CallInstr($TOKEN_REF.token));}
|
||||
| TOKEN_REF
|
||||
| TOKEN_REF {emit(new CallInstr($TOKEN_REF.token));}
|
||||
| ^(ROOT terminal)
|
||||
| ^(BANG terminal)
|
||||
;
|
|
@ -1,4 +1,4 @@
|
|||
// $ANTLR ${project.version} ${buildNumber} NFABytecodeTriggers.g 2010-05-01 11:23:08
|
||||
// $ANTLR ${project.version} ${buildNumber} NFABytecodeTriggers.g 2010-05-01 12:43:43
|
||||
|
||||
package org.antlr.v4.codegen;
|
||||
|
||||
|
@ -1321,6 +1321,7 @@ public class NFABytecodeTriggers extends NFABytecodeGenerator {
|
|||
GrammarAST STRING_LITERAL4=null;
|
||||
GrammarAST TOKEN_REF5=null;
|
||||
GrammarAST TOKEN_REF6=null;
|
||||
GrammarAST TOKEN_REF7=null;
|
||||
|
||||
try {
|
||||
// NFABytecodeTriggers.g:169:5: ( ^( STRING_LITERAL . ) | STRING_LITERAL | ^( TOKEN_REF ARG_ACTION . ) | ^( TOKEN_REF . ) | TOKEN_REF | ^( ROOT terminal ) | ^( BANG terminal ) )
|
||||
|
@ -1378,17 +1379,18 @@ public class NFABytecodeTriggers extends NFABytecodeGenerator {
|
|||
case 5 :
|
||||
// NFABytecodeTriggers.g:173:7: TOKEN_REF
|
||||
{
|
||||
match(input,TOKEN_REF,FOLLOW_TOKEN_REF_in_terminal879);
|
||||
TOKEN_REF7=(GrammarAST)match(input,TOKEN_REF,FOLLOW_TOKEN_REF_in_terminal879);
|
||||
emit(new CallInstr(TOKEN_REF7.token));
|
||||
|
||||
}
|
||||
break;
|
||||
case 6 :
|
||||
// NFABytecodeTriggers.g:174:7: ^( ROOT terminal )
|
||||
{
|
||||
match(input,ROOT,FOLLOW_ROOT_in_terminal893);
|
||||
match(input,ROOT,FOLLOW_ROOT_in_terminal894);
|
||||
|
||||
match(input, Token.DOWN, null);
|
||||
pushFollow(FOLLOW_terminal_in_terminal895);
|
||||
pushFollow(FOLLOW_terminal_in_terminal896);
|
||||
terminal();
|
||||
|
||||
state._fsp--;
|
||||
|
@ -1401,10 +1403,10 @@ public class NFABytecodeTriggers extends NFABytecodeGenerator {
|
|||
case 7 :
|
||||
// NFABytecodeTriggers.g:175:7: ^( BANG terminal )
|
||||
{
|
||||
match(input,BANG,FOLLOW_BANG_in_terminal908);
|
||||
match(input,BANG,FOLLOW_BANG_in_terminal909);
|
||||
|
||||
match(input, Token.DOWN, null);
|
||||
pushFollow(FOLLOW_terminal_in_terminal910);
|
||||
pushFollow(FOLLOW_terminal_in_terminal911);
|
||||
terminal();
|
||||
|
||||
state._fsp--;
|
||||
|
@ -1791,9 +1793,9 @@ public class NFABytecodeTriggers extends NFABytecodeGenerator {
|
|||
public static final BitSet FOLLOW_ARG_ACTION_in_terminal849 = new BitSet(new long[]{0xFFFFFFFFFFFFFFF0L,0x0000007FFFFFFFFFL});
|
||||
public static final BitSet FOLLOW_TOKEN_REF_in_terminal863 = new BitSet(new long[]{0x0000000000000004L});
|
||||
public static final BitSet FOLLOW_TOKEN_REF_in_terminal879 = new BitSet(new long[]{0x0000000000000002L});
|
||||
public static final BitSet FOLLOW_ROOT_in_terminal893 = new BitSet(new long[]{0x0000000000000004L});
|
||||
public static final BitSet FOLLOW_terminal_in_terminal895 = new BitSet(new long[]{0x0000000000000008L});
|
||||
public static final BitSet FOLLOW_BANG_in_terminal908 = new BitSet(new long[]{0x0000000000000004L});
|
||||
public static final BitSet FOLLOW_terminal_in_terminal910 = new BitSet(new long[]{0x0000000000000008L});
|
||||
public static final BitSet FOLLOW_ROOT_in_terminal894 = new BitSet(new long[]{0x0000000000000004L});
|
||||
public static final BitSet FOLLOW_terminal_in_terminal896 = new BitSet(new long[]{0x0000000000000008L});
|
||||
public static final BitSet FOLLOW_BANG_in_terminal909 = new BitSet(new long[]{0x0000000000000004L});
|
||||
public static final BitSet FOLLOW_terminal_in_terminal911 = new BitSet(new long[]{0x0000000000000008L});
|
||||
|
||||
}
|
|
@ -71,11 +71,12 @@ public class TestNFABytecodeGeneration extends BaseTest {
|
|||
"fragment D : '0'..'9'+ ;\n");
|
||||
String expecting =
|
||||
"0000:\tsplit 5\n" +
|
||||
"0005:\tsplit 5, 12\n" +
|
||||
"0012:\taccept 4\n" +
|
||||
"0015:\trange8 '0', '9'\n" +
|
||||
"0018:\tsplit 15, 25\n" +
|
||||
"0025:\tret \n";
|
||||
"0005:\tcall 18\n" +
|
||||
"0008:\tsplit 5, 15\n" +
|
||||
"0015:\taccept 4\n" +
|
||||
"0018:\trange8 '0', '9'\n" +
|
||||
"0021:\tsplit 18, 28\n" +
|
||||
"0028:\tret \n";
|
||||
checkBytecode(g, expecting);
|
||||
}
|
||||
|
||||
|
|
|
@ -59,8 +59,8 @@ public class TestNFABytecodeInterp extends BaseTest {
|
|||
"lexer grammar L;\n" +
|
||||
"I : D+ ;\n" +
|
||||
"fragment D : '0'..'9'+ ;\n");
|
||||
String expecting = "";
|
||||
checkMatches(g, "a", expecting);
|
||||
String expecting = "I, EOF";
|
||||
checkMatches(g, "32", expecting);
|
||||
}
|
||||
|
||||
public void _template() throws Exception {
|
||||
|
|
Loading…
Reference in New Issue