我必须使用动态令牌(即必须在运行时设置的令牌)初始化antlr语法。由于这种限制,我遇到了一些问题。
让我们看下面的语法文件:
open_file : OPEN COMMA FILE;
display_img : DISPLAY COMMA IMAGE;
OPEN : 'Open';
DISPLAY : 'Display';
COMMA : ',';
FILE : [A-Z0-9_]+ {isFileName()}?;
IMAGE : [A-Z0-9_]+ {isImageName()}?;
如您所见,我的第一个想法是在运行时在词法分析器中检查输入流是否对应于文件名或图像名。每种检查方法都可以访问文件名和图像名的动态列表。
当我具有相同名称的文件和图像时发生了问题。因此,如果我使用规则display_img来解析输入字符串“ Display HelloWorld”,那么lexer会将HelloWorld设置为FILE令牌(因为在IMAGE令牌之前定义),并且解析失败。
所以我更改了语法文件:
open_file : OPEN COMMA file=NAME {isFileName($file.getText())}?;
display_img : DISPLAY COMMA img=NAME {isImageName($img.getText())}?;
OPEN : 'Open';
DISPLAY : 'Display';
COMMA : ',';
NAME : [A-Z0-9_]+;
我让所有运行时标记都在单个标记类型NAME下定义,并且检查由解析器完成。 很好。
但是,现在我必须构建自动完成功能。
当我键入“ Open”并要求自动完成时,我得到一个IntervalSet,它为我提供了预期的令牌类型。在这种情况下,我将获得NAME令牌类型。
NAME不明确,可以是文件名或图像名。因此,我必须过滤完成列表以仅提供文件名。
我不知道该怎么做,因为我没有规则的背景。有人可以给我一个提示吗? 可能是我的语法文件定义不正确,但是我不知道该怎么做。