Grammar 这语法含糊不清吗?

Grammar 这语法含糊不清吗?,grammar,bison,bnf,jison,Grammar,Bison,Bnf,Jison,我试图定义一种使用很少标点符号来进行划界的语言,就像没有缩进一样。这就是我想要实现的目标: # Definition object1, object2 property1 = value1, property2 = value2 # Definition object3 property = value # Statement object1 + object2 + object3 这将定义三个具有某些属性的对象并将其添加。请注意,第一个定义使用名称列表指定了两个对象,第二

我试图定义一种使用很少标点符号来进行划界的语言,就像没有缩进一样。这就是我想要实现的目标:

# Definition
object1, object2
    property1 = value1,
    property2 = value2

# Definition
object3 property = value

# Statement
object1 + object2 + object3
这将定义三个具有某些属性的对象并将其添加。请注意,第一个定义使用名称列表指定了两个对象,第二个定义说明空格不应该很重要

尽管名称列表和属性列表之间缺少开始和结束符号,但我觉得语法并不含糊。语法指定每个名称列表后面都有一个属性列表。如果我只编写一个语法来指定定义,这一切似乎都很好,包括以下产品:

definition
    : name_list property_list
    ;

name_list
    : name
    | name_list ',' name
    ;

property_list
    : property
    | property_list ',' property
    ;

property
    : name '=' name
    ;
现在,我为语法的表达式部分添加了规则,据我所知,这是一种相当正常的方式:

expr
    : expr '+' expr
    | expr '/' expr
    | name
    ;
Jison抱怨说,在某些编号状态下,一堆不同的前瞻令牌“可能有多个操作”。减少选项通常如下所示:

- reduce by rule: name_list -> name
- reduce by rule: expr -> name

我相信语法是明确的,但我怎样才能说服吉森呢?看起来它可能需要向前看两个标记而不是一个,但这是一个盲目的猜测,Jison文档指出它(还?)不支持LL(k)语法。

您没有显示整个语法,但您的问题似乎是,它无法区分简单名称的
expr
和名称列表中只有一个名称的声明开头之间的区别。考虑输入

A B = C

第一种情况是带有一个属性的
a
的单一定义,而第二种情况是表达式
a
,后跟
B
的定义

问题是,解析器需要在看到
A
和查看
B
之前的情况后,在这两种情况之间做出决定,但它不能——它需要更多的前瞻(查看
B
之后的情况)

为了避免这种情况,你可以做很多事情,要么改变你的语言,要么(有效地)进行额外的前瞻

  • 改变语言。在这种情况下,仅仅是一个名称的语句可能没有任何意义。因此,您可以将语言更改为具有单独的
    语句
    规则,该规则不允许使用简单名称:

    statement: expr '+' expr | expr '/' expr ;
    expr: statement | name ;
    
    现在,它可以区分
    语句
    声明
    ,而不需要额外的前瞻,因为
    语句
    必须包含运算符

  • 换工具。您可以使用bison的
    %glr解析器
    选项或类似的工具来处理非LALR(1)语法。然而,我完全不确定Jison支持什么

  • 在lexer中模拟额外的前瞻。你可以让你的lexer为你做额外的前瞻。您可以有一个与
    [a-zA-Z]+[\t\n]*=
    匹配的lexer模式(即名称后面跟一个=符号),并让它返回一个特殊的
    propname
    标记,而不是
    name
    。然后您的
    属性
    规则变为:

    property: propname name ;
    

  • 是的,这是模糊语法。从中获取帮助如果不查看
    属性列表
    @DavidGorsline的规则,很难判断我添加了
    属性列表
    属性
    产品。我只是不想把问题问得太长。@GrijeshChauhan谢谢,我会尽力理解的。谢谢!这些都是很好的建议,;我会努力实现它们。我以前在尝试禁止使用单名语句时遇到了问题,但您描述的内容非常简单,我不明白为什么它不起作用!
    property: propname name ;