我有这个语法:
grammar PrimeGrammar;
options
{
backtrack=true;
language = CSharp3;
memoize=true;
}
@parser::header
{
using System;
}
@parser::members
{
public int[] ObjInput = new int[]{1,2,3,4,5,6,7,8,9,10,11,12,13};
private int CurrObj() //current object
{
int id = ((CommonTokenStream)InputStream).Lt(1).TokenIndex;
return ObjInput[id];
}
private bool isPrime()
{
int number = CurrObj();
int boundary = (int)Math.Floor(Math.Sqrt(number));
if (number == 1) return false;
if (number == 2) return true;
for (int i = 2; i <= boundary; ++i) {
if (number % i == 0) return false;
}
return true;
}
private bool isEven()
{
int number = CurrObj();
return number % 2 == 0;
}
}
parse : anyObj*;
////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////RULEs SECTIONs///////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
anyObj : primeSequence
| evenSequence
| OBJ
;
////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////Prime Section////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
prime : {isPrime()}? OBJ;
primeSequence : prime (OBJ prime)+;
////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////Even Section/////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
even : {isEven()}? OBJ;
evenSequence : even (OBJ even)+;
OBJ : .;
它只是与对象相关的语法,可以解析 int 对象而不是字符或内置标记。 ( ObjInput 是这种情况下的对象数组)要运行示例,您只需发送Parser相同数量的标记,放置在 ObjInput 字段内。
所以,在解析之前我只是设置这个数组并在相同数量的任何垃圾代币上运行我的最高规则。但是存在一个问题:如果带有谓词的规则失败,则不会发生回溯,状态机只会继续运行直到结束...
如果谓词失败,如何强制ANTLR转到上一个成功状态?我认为C#中的backtrack-option刚刚被破坏,如果我在Java上重写它,这个语法在ANTLRWorks中完美运行。
有什么想法吗?我能做什么,而不是写一堆外观指令?