handles nongreedy + and * loops. rewinds properly to last good accept if we kept going and failed.

[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 6828]
This commit is contained in:
parrt 2010-04-30 17:37:07 -08:00
parent 6b55114dd0
commit 541350bbe3
3 changed files with 245 additions and 211 deletions

View File

@ -193,6 +193,8 @@ workLoop:
List<Integer> reach = new ArrayList<Integer>();
int prevAcceptAddr = Integer.MAX_VALUE;
int prevAcceptLastCharIndex = -1;
int prevAcceptInputMarker = -1;
int firstAcceptInputMarker = -1;
addToClosure(closure, ip);
do { // while more work
c = input.LA(1);
@ -238,12 +240,15 @@ processOneChar:
// choose longest match so far regardless of rule priority
System.out.println("replacing old best match @ "+prevAcceptAddr);
prevAcceptAddr = ip-1;
prevAcceptInputMarker = input.mark();
firstAcceptInputMarker = prevAcceptInputMarker;
}
else if ( tokenLastCharIndex == prevAcceptLastCharIndex ) {
// choose first rule matched if match is of same length
if ( ip-1 < prevAcceptAddr ) { // it will see both accepts for ambig rules
System.out.println("replacing old best match @ "+prevAcceptAddr);
prevAcceptAddr = ip-1;
prevAcceptInputMarker = input.mark();
}
}
// if we reach accept state, toss out any addresses in rest
@ -285,6 +290,11 @@ processOneChar:
if ( prevAcceptAddr >= code.length ) return Token.INVALID_TOKEN_TYPE;
int ttype = getShort(code, prevAcceptAddr+1);
System.out.println("done at index "+input.index());
System.out.println("accept marker="+prevAcceptInputMarker);
input.rewind(prevAcceptInputMarker); // does nothing if we accept'd at input.index() but might need to rewind
input.release(firstAcceptInputMarker); // kill any other markers in stream we made
System.out.println("leaving with index "+input.index());
return ttype;
}

View File

@ -9,6 +9,10 @@ options {
@header {
package org.antlr.v4.codegen;
import org.antlr.v4.tool.GrammarAST;
import org.antlr.v4.tool.GrammarASTWithOptions;
import java.util.Collections;
import java.util.Map;
import java.util.HashMap;
}
/*
@ -83,6 +87,10 @@ treeSpec
;
ebnf
@init {
GrammarASTWithOptions blk = (GrammarASTWithOptions)$start.getChild(0);
String greedyOption = blk.getOption("greedy");
}
: ^(astBlockSuffix block)
| {
SplitInstr S = new SplitInstr(2);
@ -97,15 +105,16 @@ ebnf
int start=ip;
SplitInstr S = new SplitInstr(2);
emit(S);
int blk = ip;
int blkStart = ip;
}
^(CLOSURE block)
{
JumpInstr J = new JumpInstr();
emit(J);
J.target = start;
S.addrs.add(blk);
S.addrs.add(ip); // reverse for nongreedy
S.addrs.add(blkStart);
S.addrs.add(ip);
if ( greedyOption!=null && greedyOption.equals("false") ) Collections.reverse(S.addrs);
}
| {int start=ip;} ^(POSITIVE_CLOSURE block)
{
@ -114,6 +123,7 @@ ebnf
int stop = ip;
S.addrs.add(start);
S.addrs.add(stop);
if ( greedyOption!=null && greedyOption.equals("false") ) Collections.reverse(S.addrs);
}
| block
;

File diff suppressed because it is too large Load Diff