Antlr语法谓词不匹配

Antlr语法谓词不匹配,antlr,antlr3,Antlr,Antlr3,我的语法如下: rule : (PATH)=> (PATH) SLASH WORD {System.out.println("file: " + $WORD.text + " path: " + $PATH.text);}; WORD : ('a'..'z')+; SLASH : '/'; PATH : (WORD SLASH)* WORD; 但它不适用于“a/b/c/filename”这样的字符串。 我想我可以解决这个“路径”问题,即语法谓词特性的问题。也许我在这里

我的语法如下:

rule  : (PATH)=> (PATH) SLASH WORD
   {System.out.println("file: " + $WORD.text + " path: " + $PATH.text);};
WORD  : ('a'..'z')+;
SLASH   : '/';
PATH    : (WORD SLASH)* WORD;
但它不适用于“a/b/c/filename”这样的字符串。
我想我可以解决这个“路径”问题,即语法谓词特性的问题。也许我在这里做错了什么,我必须重新定义语法。对这个问题有什么建议吗?

您必须理解,语法谓词不会导致语法分析器向词法分析器提供某种方向w.r.t。语法分析器“希望”检索什么标记。语法谓词用于强制解析器在现有令牌流中向前看以解决歧义(强调“现有”:解析器无法控制创建什么令牌!)

lexer独立于解析器运行,以系统的方式创建标记:

  • 它试图匹配尽可能多的字符
  • 每当两个(或更多)规则匹配相同数量的字符时,首先定义的规则将优先于随后定义的规则
  • 因此,在您的情况下,给定输入
    “a/b/c/filename”
    ,lexer将贪婪地将整个输入匹配为单个
    路径
    标记

    如果要获取文件名,请从
    路径中检索:

    rule  : PATH
            {
             String file = $PATH.text.substring($PATH.text.lastIndexOf('/') + 1);
             System.out.println("file: " + file + ", path: " + $PATH.text);
            }
          ;
    WORD  : ('a'..'z')+;
    SLASH : '/';
    PATH  : (WORD SLASH)* WORD;
    
    或创建与路径匹配的解析器规则:

    rule  : dir WORD
            {
             System.out.println("file: " + $WORD.text + ", dir: " + $dir.text);
            }
          ;
    dir   : (WORD SLASH)+;
    WORD  : ('a'..'z')+;
    SLASH : '/';