代码之家  ›  专栏  ›  技术社区  ›  peter.murray.rust

ANTLR:“规则范围内缺少属性访问”问题

  •  8
  • peter.murray.rust  · 技术社区  · 16 年前

    我试图构建一个ANTLR语法来解析标记的句子,例如:

    DT The NP cat VB ate DT a NP rat
    

    fragment TOKEN  :   (('A'..'Z') | ('a'..'z'))+;
    fragment WS :   (' ' | '\t')+;
    WSX :   WS;
    DTTOK   :   ('DT' WS TOKEN);
    NPTOK   :   ('NP' WS TOKEN);
    nounPhrase:  (DTTOK WSX NPTOK);
    chunker : nounPhrase {System.out.println("chunk found "+"("+$nounPhrase+")");};
    

    missing attribute access on rule scope: nounPhrase “在最后一行。

    [我还是ANTLR的新手,尽管有些语法有效,但它仍然是试错法。在运行如此小的语法时,我也经常遇到“OutOfMemory”错误——欢迎任何帮助。]

    4 回复  |  直到 16 年前
        1
  •  9
  •   Brad Mace Mike King    14 年前

    $nounPhrase 范围(例如 $nounPhrase.text ).

    multiple_names returns [List<Name> names]
    @init {
        names = new ArrayList<Name>(4);
    }
     : a=fullname ' AND ' b=fullname { names.add($a.value); names.add($b.value); };
    

    结果“ 规则全名的未知属性 “所以我试过了

    multiple_names returns [List<Name> names]
    @init {
        names = new ArrayList<Name>(4);
    }
     : a=fullname ' AND ' b=fullname { names.add($a); names.add($b); };
    

    “.通过查看生成的解析器方法,我清楚地知道了我需要做什么。虽然有一些神秘的部分,但与作用域(变量)相关的部分很容易理解:

    public final List<Name> multiple_names() throws RecognitionException {
        List<Name> names = null;        // based on "returns" clause of rule definition
        Name a = null;                  // based on scopes declared in rule definition
        Name b = null;                  // based on scopes declared in rule definition
        names = new ArrayList<Name>(4); // snippet inserted from `@init` block
    
        try {
            pushFollow(FOLLOW_fullname_in_multiple_names42);
            a=fullname();
            state._fsp--;
            match(input,189,FOLLOW_189_in_multiple_names44); 
            pushFollow(FOLLOW_fullname_in_multiple_names48);
            b=fullname();
            state._fsp--;
            names.add($a); names.add($b);// code inserted from {...} block
        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }
        finally {
            // do for sure before leaving
        }
        return names;                    // based on "returns" clause of rule definition
    }
    

    fullname 规则是返回的实例 Name 类,所以在这种情况下,我需要的只是:

    multiple_names returns [List<Name> names]
    @init {
        names = new ArrayList<Name>(4);
    }
     : a=fullname ' AND ' b=fullname { names.add(a); names.add(b); };
    

    在你的情况下,你需要的版本可能不同,但你通常可以通过查看生成的代码很容易地找到它。

        2
  •  3
  •   Brad Mace Mike King    14 年前

    在原始语法中,为什么不包含它所要求的属性,很可能是:

    chunker : nounPhrase {System.out.println("chunk found "+"("+$nounPhrase.text+")");};
    

    chunker http://www.antlr.org/wiki/display/ANTLR3/Attribute+and+Dynamic+Scopes

    我认为你的分块规则应该稍微改变一下,而不是 $nounPhrase $nounPhrase.text . text nounPhrase 规则。

        3
  •  1
  •   Dylan Knowles    12 年前

    如果你不小心做了一些愚蠢的事情,比如 $thing.$attribute 你是什么意思 $thing.attribute missing attribute access on rule scope

        4
  •  0
  •   peter.murray.rust    16 年前

    WS  :    (' '|'\t')+;
    TOKEN   :   (('A'..'Z') | ('a'..'z'))+;
    dttok   :   'DT' WS TOKEN;
    nntok   :   'NN' WS TOKEN; 
    nounPhrase :    (dttok WS nntok);
    chunker :  nounPhrase ;
    

    问题是我在词法分析器和解析器之间搞混了(这显然很常见)。大写项是词法项,解析器中的小写项。现在看来,这似乎奏效了。(注意,我已经将NP改为NN)。