0

我有以下语法:

SPACE : (' '|'\t'|'\n'|'\r')+ {$channel = HIDDEN;};
NAME_TAG : 'name';
IS_TAG : 'is';

START : 'START';
END : ('END START') => 'END START'  ;

WORD    : 'A'..'Z'+;

rule :  START NAME_TAG IS_TAG WORD END;

并想要解析语言,例如:“START name is END END START”。这里的问题是 END 标记,因为 'END ' (Word + SPACE) 被误解了。我认为这里的正确方法是使用句法谓词(END-token),但也许我错了。

4

1 回答 1

1

我不会创建WORD由空格分隔的 2 个(或更多)的标记。为什么不标记'END'为和END-token 然后做这样的事情:

rule     : START NAME_TAG IS_TAG word END START;
word     : WORD | END; // expand this rule, as you see fit
NAME_TAG : 'name';
IS_TAG   : 'is';
START    : 'START';
END      : 'END';
WORD     : 'A'..'Z'+;
SPACE    : (' '|'\t'|'\n'|'\r')+ {$channel = HIDDEN;};

这将解析"START name is END END START"为以下解析树:

在此处输入图像描述

编辑

如果谓词失败,您做错的是给词法分析器规则恢复的可能性。这是谓词的正确用法:

rule     :  START NAME_TAG IS_TAG WORD END;

SPACE    : (' '|'\t'|'\n'|'\r')+ {$channel = HIDDEN;};
NAME_TAG : 'name';
IS_TAG   : 'is';
START    : 'START';
WORD     : ('END START')=> 'END START' {$type=END;}
         | 'A'..'Z'+
         ;

fragment END : ;
于 2012-04-05T20:56:52.837 回答