1

我正在尝试解决如何处理ANTLR. 我需要正确解析标识符或带有大小前缀的标识符。首先我想到了这个错误的语法

grammar PrefixProblem;
options       
{   
    language = Java;
}
goal: (size_prefix ':')? id;
size_prefix: B;
id: LETTER+;
LETTER: 'A'..'Z' ;
B: 'B';
WSFULL:(' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN;};

我需要处理Bas IDB:Bid Bprefix一样B。它没有用。

然后我找到了两个解决这个问题的方法。

grammar PrefixSolution1;
options       
{   
    language = Java;
}
goal: (size_prefix ':')? id;
size_prefix: B;
id: (LETTER | B)+;
LETTER: 'A' | 'C'..'Z' ;
B: 'B';
WSFULL:(' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN;};

在上面的代码中,Blexer规则中删除并在id规则中连接。

grammar PrefixSolution2;
options       
{   
    language = Java;
}
goal: PREFIX_VAR;
PREFIX_VAR: (B WSFULL* ':' WSFULL*)? ID;
fragment ID: (LETTER)+;
fragment LETTER: 'A'..'Z' ;
fragment B: 'B';
WSFULL:(' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN;};

在这里,我只是将规则移至lexer.

PrefixSolution1有一个主要缺点,我需要将词法分析器规则分成更小的块,然后再连接起来。

PrefixSolution2:这种方法导致我需要始终考虑应该忽略的空白字符。

对我来说,这两种解决方案都会导致为整个语言编写语法变得一团糟。还有其他解决方案吗?如果不是,哪种方式是最优化的?

所有源代码都可以在这里找到

4

2 回答 2

1

我不会和他们中的任何一个一起去。我只是创建ID令牌而不是 B令牌(或创建PREFIX_VAR令牌:这属于解析器)。

您可以在解析器规则中capB使用消除歧义的语义谓词1来匹配大写字母 B ( ),如下所示:

grammar Test;

goal
 : (prefixVar | ID)+ EOF
 ;

prefixVar
 : capB ':' ID 
 ;

capB
 : {input.LT(1).getText().equals("B")}? ID
 ;

ID : LETTER+;
WS : (' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN;};

fragment LETTER: 'A'..'Z' ;

这会将输入解析B:B B B:C为以下解析树:

在此处输入图像描述

1 ANTLR 中的“语义谓词”是什么?

于 2012-04-26T11:57:20.117 回答
0

试试这个:

grammar PrefixProblem;


options       
{   
language = Java;
}

 goal: (size_prefix ':')? (id|B);

size_prefix: B;

id: LETTER+;

LETTER: 'A'|'C'..'Z' ;

B: 'B';

WSFULL:(' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN;};
于 2012-04-26T11:42:06.607 回答