grammar
  • pegjs
  • ambiguous-grammar
  • 2014-10-30 74 views 2 likes 
    2

    我需要在谓词的帮助下创建一个语法。下面的语法在给定的情况下失败。PEGJS谓词语法

    startRule = a:namespace DOT b:id OPEN_BRACE CLOSE_BRACE {return {"namespace": a, "name": b}} 
    
    namespace = id (DOT id)* 
    DOT = '.'; 
    OPEN_BRACE = '('; 
    CLOSE_BRACE = ')'; 
    id = [a-zA-Z]+; 
    

    它无法给定的输入为

    com.mytest.create(); 
    

    这应该给“创造”在结果部分“姓名”键的值。

    任何帮助将是伟大的。

    回答

    1

    这里有几件事。

    最重要的是,你必须知道,PEG 是贪婪。这意味着您的(DOT id)*规则会匹配所有DOT ID序列,包括您在startRule中拥有的序列号为DOT b:id

    这可以使用lookahead来解决。

    另一件事是,你必须记住使用join,因为默认情况下它会返回每个字符作为数组的成员。

    我还为分号添加了一条规则。

    试试这个:

    start = 
        namespace:namespace DOT name:string OPEN_BRACE CLOSE_BRACE SM nl? 
        { 
         return { namespace : namespace, name : name }; 
        } 
    
    /* Here I'm using the lookahead: (member !OPEN_BRACE)* */ 
    namespace = 
        first:string rest:(member !OPEN_BRACE)* 
        { 
         rest = rest.map(function (x) { return x[0]; }); 
         rest.unshift(first); 
         return rest; 
        } 
    
    member = 
        DOT str:string 
        { return str; } 
    
    DOT = 
        '.' 
    
    OPEN_BRACE = 
        '(' 
    
    CLOSE_BRACE = 
        ')' 
    
    SM = 
        ';' 
    
    nl = 
        "\n" 
    
    string = 
        str:[a-zA-Z]+ 
        { return str.join(''); } 
    

    而且据我所知,我正确地分析该行。

    +1

    谢谢你的帮助,它的工作。我不知道pegjs是贪婪的。 – djadmin 2014-11-06 09:27:42

    相关问题