From f3e6d4644de5f0383322c10cbf141b98416f23dc Mon Sep 17 00:00:00 2001 From: parrt Date: Sat, 1 May 2010 12:46:47 -0800 Subject: [PATCH] got INT calls DIGIT working [git-p4: depot-paths = "//depot/code/antlr4/main/": change = 6830] --- .../src/org/antlr/v4/runtime/nfa/NFA.java | 43 +++++++------------ .../v4/codegen/NFABytecodeGenerator.java | 43 +++++++++++-------- .../antlr/v4/codegen/NFABytecodeTriggers.g | 2 +- .../antlr/v4/codegen/NFABytecodeTriggers.java | 22 +++++----- .../v4/test/TestNFABytecodeGeneration.java | 11 ++--- .../antlr/v4/test/TestNFABytecodeInterp.java | 4 +- 6 files changed, 61 insertions(+), 64 deletions(-) diff --git a/runtime/Java/src/org/antlr/v4/runtime/nfa/NFA.java b/runtime/Java/src/org/antlr/v4/runtime/nfa/NFA.java index 33c988036..0248d3188 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/nfa/NFA.java +++ b/runtime/Java/src/org/antlr/v4/runtime/nfa/NFA.java @@ -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 ruleToAddr; public int[] tokenTypeToAddr; - // 7, 29 -> rule - // 7..28, 29..len - public NFA(byte[] code, Map ruleToAddr) { + public NFA(byte[] code, Map 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 } } diff --git a/tool/src/org/antlr/v4/codegen/NFABytecodeGenerator.java b/tool/src/org/antlr/v4/codegen/NFABytecodeGenerator.java index 9097e2e05..6dacd0598 100644 --- a/tool/src/org/antlr/v4/codegen/NFABytecodeGenerator.java +++ b/tool/src/org/antlr/v4/codegen/NFABytecodeGenerator.java @@ -194,24 +194,32 @@ public class NFABytecodeGenerator extends TreeParser { } /** Given any block of alts, return list of instruction objects */ - public static List 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 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 instrs) { + public static byte[] getByteCode(Map ruleToAddr, List 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, diff --git a/tool/src/org/antlr/v4/codegen/NFABytecodeTriggers.g b/tool/src/org/antlr/v4/codegen/NFABytecodeTriggers.g index 781f169b8..e7f038983 100644 --- a/tool/src/org/antlr/v4/codegen/NFABytecodeTriggers.g +++ b/tool/src/org/antlr/v4/codegen/NFABytecodeTriggers.g @@ -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) ; \ No newline at end of file diff --git a/tool/src/org/antlr/v4/codegen/NFABytecodeTriggers.java b/tool/src/org/antlr/v4/codegen/NFABytecodeTriggers.java index e82d87ce8..d7f80c668 100644 --- a/tool/src/org/antlr/v4/codegen/NFABytecodeTriggers.java +++ b/tool/src/org/antlr/v4/codegen/NFABytecodeTriggers.java @@ -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}); } \ No newline at end of file diff --git a/tool/test/org/antlr/v4/test/TestNFABytecodeGeneration.java b/tool/test/org/antlr/v4/test/TestNFABytecodeGeneration.java index 314c16b26..1c737d0f7 100644 --- a/tool/test/org/antlr/v4/test/TestNFABytecodeGeneration.java +++ b/tool/test/org/antlr/v4/test/TestNFABytecodeGeneration.java @@ -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); } diff --git a/tool/test/org/antlr/v4/test/TestNFABytecodeInterp.java b/tool/test/org/antlr/v4/test/TestNFABytecodeInterp.java index f303fa1da..b9bbb3dae 100644 --- a/tool/test/org/antlr/v4/test/TestNFABytecodeInterp.java +++ b/tool/test/org/antlr/v4/test/TestNFABytecodeInterp.java @@ -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 {