代码之家  ›  专栏  ›  技术社区  ›  Simone Margaritelli

野牛:单个规则中的可选令牌

  •  10
  • Simone Margaritelli  · 技术社区  · 15 年前

    我正在使用gnu bison 2.4.2为我正在研究的一种新语言编写语法,我有一个问题。 当我指定一个规则时,假设:

    statement : T_CLASS T_IDENT  '{' T_CLASS_MEMBERS '}' {
               // create a node for the statement ...
    }
    

    例如,如果我对规则有一个变化

    statement : T_CLASS T_IDENT T_EXTENDS T_IDENT_LIST  '{' T_CLASS_MEMBERS '}' {
               // create a node for the statement ...
    }
    

    其中(来自Flex扫描仪规则):

    "class"                     return T_CLASS;
    "extends"                   return T_EXTENDS;
    [a-zA-Z\_][a-zA-Z0-9\_]*    return T_IDENT;
    

    (而且t摲id摲u list是逗号分隔标识符的规则)。

    是否有任何方法只在一个规则中指定所有这些内容,并将“t_扩展t_标识列表”设置为可选? 我已经试过了

     T_CLASS T_IDENT (T_EXTENDS T_IDENT_LIST)? '{' T_CLASS_MEMBERS '}' {
         // create a node for the statement ...
     } 
    

    但是野牛给了我一个错误。

    谢谢

    3 回复  |  直到 11 年前
        1
  •  10
  •   Jerry Coffin    15 年前

    长话短说,不,bison只处理lalr(1)语法,这意味着它只使用一个lookahead符号。你需要的是这样的东西:

    statement: T_CLASS T_IDENT extension_list '{' ...
    
    extension_list: 
                  | T_EXTENDS T_IDENT_LIST
                  ;
    

    不过,还有其他的解析器生成器可以处理更通用的语法。如果内存可用,那么其中一些可以相对直接地支持可选元素,就像您所要求的那样。

        2
  •  1
  •   Jack    15 年前

    你为什么不用选择把它们分开呢?( | )操作员?

    statement:
      T_CLASS T_IDENT T_EXTENDS T_IDENT_LIST  '{' T_CLASS_MEMBERS '}'
      | T_CLASS T_IDENT  '{' T_CLASS_MEMBERS '}'
    

    我认为你不能仅仅因为这是一个LALR(1)自下而上的解析器就这么做,你需要一些不同的东西,比如ll(k)(antlr?)做你想做的事……

        3
  •  0
  •   Michael Krelin - hacker    15 年前

    我想你能做的最多的就是

    statement : T_CLASS T_IDENT  '{' T_CLASS_MEMBERS '}'
        | T_CLASS T_IDENT T_EXTENDS T_IDENT_LIST  '{' T_CLASS_MEMBERS '}' {
    }