backtrack=true
применяется только к правилам парсера: не к правилам лексера.Поэтому, когда лексер натыкается на INTEGER SPACE
, за которым следует что-то другое , чем INTEGER
, лексер выдаст ошибку / исключение: он не вернется назадREF
и создайте вместо него токен INTEGER
и SPACE
.
Но REF
не должно быть правилом лексера, а правилом синтаксического анализатора:
ref
: INTEGER SPACE INTEGER SPACE 'R'
;
Edit
Я нахожусь в Linux и поэтому не могу проверить цель C # (по крайней мере, мне никогда не удавалось заставить цель CSharp3
работать внутри MonoDevelop).Но вот демонстрационная версия Java:
grammar Pdf;
public r
: ( ref {System.out.println("ref = '" + $ref.text + "'");}
| INTEGER {System.out.println("INTEGER = '" + $INTEGER.text + "'");}
| SPACE {System.out.println("SPACE = '" + $SPACE.text + "'");}
)*
EOF
;
ref
: INTEGER SPACE INTEGER SPACE 'R'
;
INTEGER
: DIGIT+;
SPACE
: ' '
;
fragment DIGIT
: '0'..'9'
;
Вы можете протестировать анализатор с помощью класса:
import org.antlr.runtime.*;
public class Main {
public static void main(String[] args) throws Exception {
PdfLexer lexer = new PdfLexer(new ANTLRStringStream("97 98 10 0 R 100 101"));
PdfParser parser = new PdfParser(new CommonTokenStream(lexer));
parser.r();
}
}
, и если вы запустите этот класс, будет напечатано следующее:
INTEGER = '97'
SPACE = ' '
INTEGER = '98'
SPACE = ' '
ref = '10 0 R'
SPACE = ' '
INTEGER = '100'
SPACE = ' '
INTEGER = '101'
, что именно так, как я ожидал.