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;
|
import java.util.Map;
|
||||||
|
|
||||||
/** http://swtch.com/~rsc/regexp/regexp2.html */
|
/** 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 class NFA {
|
||||||
public byte[] code;
|
public byte[] code;
|
||||||
Map<String, Integer> ruleToAddr;
|
Map<String, Integer> ruleToAddr;
|
||||||
public int[] tokenTypeToAddr;
|
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.code = code;
|
||||||
this.ruleToAddr = ruleToAddr;
|
this.ruleToAddr = ruleToAddr;
|
||||||
|
this.tokenTypeToAddr = tokenTypeToAddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int exec(CharStream input, String ruleName) {
|
public int exec(CharStream input, String ruleName) {
|
||||||
|
@ -310,7 +285,7 @@ processOneChar:
|
||||||
case Bytecode.SAVE :
|
case Bytecode.SAVE :
|
||||||
int labelIndex = getShort(code, ip);
|
int labelIndex = getShort(code, ip);
|
||||||
ip += 2;
|
ip += 2;
|
||||||
addToClosure(closure, ip, alt, context); // do closure pass SAVE
|
addToClosure(closure, ip, alt, context); // do closure past SAVE
|
||||||
// TODO: impl
|
// TODO: impl
|
||||||
break;
|
break;
|
||||||
case Bytecode.SPLIT :
|
case Bytecode.SPLIT :
|
||||||
|
@ -321,6 +296,18 @@ processOneChar:
|
||||||
addToClosure(closure, getShort(code, ip+i*2), alt, context);
|
addToClosure(closure, getShort(code, ip+i*2), alt, context);
|
||||||
}
|
}
|
||||||
break;
|
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 */
|
/** Given any block of alts, return list of instruction objects */
|
||||||
public static List<Instr> getInstructions(GrammarAST blk, int acceptValue) {
|
// public static List<Instr> getInstructions(GrammarAST blk, int acceptValue) {
|
||||||
GrammarASTAdaptor adaptor = new GrammarASTAdaptor();
|
// GrammarASTAdaptor adaptor = new GrammarASTAdaptor();
|
||||||
CommonTreeNodeStream nodes = new CommonTreeNodeStream(adaptor,blk);
|
// CommonTreeNodeStream nodes = new CommonTreeNodeStream(adaptor,blk);
|
||||||
NFABytecodeTriggers gen = new NFABytecodeTriggers(nodes);
|
// NFABytecodeTriggers gen = new NFABytecodeTriggers(nodes);
|
||||||
try {
|
// try {
|
||||||
gen.block();
|
// gen.block();
|
||||||
gen.emit(new NFABytecodeGenerator.AcceptInstr(acceptValue));
|
// gen.emit(new NFABytecodeGenerator.AcceptInstr(acceptValue));
|
||||||
}
|
// }
|
||||||
catch (Exception e){
|
// catch (Exception e){
|
||||||
e.printStackTrace(System.err);
|
// e.printStackTrace(System.err);
|
||||||
}
|
// }
|
||||||
return gen.instrs;
|
// 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);
|
Instr last = instrs.get(instrs.size() - 1);
|
||||||
int size = last.addr + last.nBytes();
|
int size = last.addr + last.nBytes();
|
||||||
byte[] code = new byte[size];
|
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) {
|
for (Instr I : instrs) {
|
||||||
I.write(code);
|
I.write(code);
|
||||||
}
|
}
|
||||||
|
@ -255,12 +263,11 @@ public class NFABytecodeGenerator extends TreeParser {
|
||||||
e.printStackTrace(System.err);
|
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);
|
System.out.println("rule addrs="+ruleToAddr);
|
||||||
|
|
||||||
NFA nfa = new NFA(code, ruleToAddr);
|
return new NFA(code, ruleToAddr, tokenTypeToAddr);
|
||||||
nfa.tokenTypeToAddr = tokenTypeToAddr;
|
|
||||||
return nfa;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Write value at index into a byte array highest to lowest byte,
|
/** Write value at index into a byte array highest to lowest byte,
|
||||||
|
|
|
@ -170,7 +170,7 @@ terminal
|
||||||
| STRING_LITERAL {emitString($STRING_LITERAL.token);}
|
| STRING_LITERAL {emitString($STRING_LITERAL.token);}
|
||||||
| ^(TOKEN_REF ARG_ACTION .) {emit(new CallInstr($TOKEN_REF.token));}
|
| ^(TOKEN_REF ARG_ACTION .) {emit(new CallInstr($TOKEN_REF.token));}
|
||||||
| ^(TOKEN_REF .) {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)
|
| ^(ROOT terminal)
|
||||||
| ^(BANG 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;
|
package org.antlr.v4.codegen;
|
||||||
|
|
||||||
|
@ -1321,6 +1321,7 @@ public class NFABytecodeTriggers extends NFABytecodeGenerator {
|
||||||
GrammarAST STRING_LITERAL4=null;
|
GrammarAST STRING_LITERAL4=null;
|
||||||
GrammarAST TOKEN_REF5=null;
|
GrammarAST TOKEN_REF5=null;
|
||||||
GrammarAST TOKEN_REF6=null;
|
GrammarAST TOKEN_REF6=null;
|
||||||
|
GrammarAST TOKEN_REF7=null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// NFABytecodeTriggers.g:169:5: ( ^( STRING_LITERAL . ) | STRING_LITERAL | ^( TOKEN_REF ARG_ACTION . ) | ^( TOKEN_REF . ) | TOKEN_REF | ^( ROOT terminal ) | ^( BANG terminal ) )
|
// 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 :
|
case 5 :
|
||||||
// NFABytecodeTriggers.g:173:7: TOKEN_REF
|
// 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;
|
break;
|
||||||
case 6 :
|
case 6 :
|
||||||
// NFABytecodeTriggers.g:174:7: ^( ROOT terminal )
|
// 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);
|
match(input, Token.DOWN, null);
|
||||||
pushFollow(FOLLOW_terminal_in_terminal895);
|
pushFollow(FOLLOW_terminal_in_terminal896);
|
||||||
terminal();
|
terminal();
|
||||||
|
|
||||||
state._fsp--;
|
state._fsp--;
|
||||||
|
@ -1401,10 +1403,10 @@ public class NFABytecodeTriggers extends NFABytecodeGenerator {
|
||||||
case 7 :
|
case 7 :
|
||||||
// NFABytecodeTriggers.g:175:7: ^( BANG terminal )
|
// 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);
|
match(input, Token.DOWN, null);
|
||||||
pushFollow(FOLLOW_terminal_in_terminal910);
|
pushFollow(FOLLOW_terminal_in_terminal911);
|
||||||
terminal();
|
terminal();
|
||||||
|
|
||||||
state._fsp--;
|
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_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_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_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_ROOT_in_terminal894 = new BitSet(new long[]{0x0000000000000004L});
|
||||||
public static final BitSet FOLLOW_terminal_in_terminal895 = new BitSet(new long[]{0x0000000000000008L});
|
public static final BitSet FOLLOW_terminal_in_terminal896 = new BitSet(new long[]{0x0000000000000008L});
|
||||||
public static final BitSet FOLLOW_BANG_in_terminal908 = new BitSet(new long[]{0x0000000000000004L});
|
public static final BitSet FOLLOW_BANG_in_terminal909 = new BitSet(new long[]{0x0000000000000004L});
|
||||||
public static final BitSet FOLLOW_terminal_in_terminal910 = new BitSet(new long[]{0x0000000000000008L});
|
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");
|
"fragment D : '0'..'9'+ ;\n");
|
||||||
String expecting =
|
String expecting =
|
||||||
"0000:\tsplit 5\n" +
|
"0000:\tsplit 5\n" +
|
||||||
"0005:\tsplit 5, 12\n" +
|
"0005:\tcall 18\n" +
|
||||||
"0012:\taccept 4\n" +
|
"0008:\tsplit 5, 15\n" +
|
||||||
"0015:\trange8 '0', '9'\n" +
|
"0015:\taccept 4\n" +
|
||||||
"0018:\tsplit 15, 25\n" +
|
"0018:\trange8 '0', '9'\n" +
|
||||||
"0025:\tret \n";
|
"0021:\tsplit 18, 28\n" +
|
||||||
|
"0028:\tret \n";
|
||||||
checkBytecode(g, expecting);
|
checkBytecode(g, expecting);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,8 +59,8 @@ public class TestNFABytecodeInterp extends BaseTest {
|
||||||
"lexer grammar L;\n" +
|
"lexer grammar L;\n" +
|
||||||
"I : D+ ;\n" +
|
"I : D+ ;\n" +
|
||||||
"fragment D : '0'..'9'+ ;\n");
|
"fragment D : '0'..'9'+ ;\n");
|
||||||
String expecting = "";
|
String expecting = "I, EOF";
|
||||||
checkMatches(g, "a", expecting);
|
checkMatches(g, "32", expecting);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void _template() throws Exception {
|
public void _template() throws Exception {
|
||||||
|
|
Loading…
Reference in New Issue