1

我有一种形式的脚本语言: <keyword> = <text>,

Where<text>可以包含关键字,有时<text>可以包含说明,具体取决于<keyword>使用的内容。

我正在尝试<text>根据使用的内容来处理<keyword>

/* lang.g */
grammar lang;

/* parser rules */
script     : assignment+ ;

assignment : keyword VALUE ;

/* cannot do the following (but I would like to)

assignment : command | command_b | display ;
command    : COMMAND '=' /* parser rules for command */ ',' ;
command_b  : COMMAND_B '=' /* parser rules for command_b */ ',' ;
display    : DISPLAY '=' ~(',')+ ',' ;
*/

/* lexer rules */
VALUE      : '='! ~(',')+ ','!

COMMAND    : 'command' ;
COMMAND_B  : 'command_b' ;
DISPLAY    : 'display' ;

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

示例输入文件:

command = goto->step_b,
display = this is some plain text. command keyword used,
command_b = read_file:"readme.txt",

我希望能够使用 ANTLR 以不同的方式处理command和规则来解析所有内容,command_bdisplay无需使用目标语言来协助。使用上面的 *.g 文件;第一行有commandgoto->step_b作为标记。 goto->step_b需要进一步解析,让 ANTLR 完成所有这些工作而不是目标语言会很好。

如果没有办法直接做到这一点,我想我会分两个阶段完成。

  1. 使用上面的 *.g 文件来解析输入文件
  2. 剔除除commandcommand_b节点之外的所有内容;仅使用为commandcommand_b语法定义的语法将这些节点馈送到另一个解析器。

有没有办法使用一个语法来解析脚本,这样我就可以处理commandcommand_b不同于任何其他规则的方式处理/规则?还是我必须分多个阶段处理脚本文件?

谢谢你的帮助。

乔什

4

1 回答 1

1

在这里看看我的答案:

antlr 标识符名称与预定义函数名称相同导致 MismatchedTokenException

您可以使用消除歧义的语义谓词将这些规则排除在您的语法之外:

COMMAND    : 'command' ;
COMMAND_B  : 'command_b' ;
DISPLAY    : 'display' ;

相反,您将编写如下规则:

functions_stats 
  :   {input.LT(1).getText().equals("command")}? '=' /* parser rules for command */ ',' ;  
  ;

语义谓词中的操作是特定于语言的,因此可能会根据您的目标语言而有所不同。它适用于 Java,可能也适用于其他一些。

于 2013-02-22T21:18:20.583 回答