LALR语法,尾随逗号和多行列表赋值

时间:2012-03-13 22:17:59

标签: python grammar yacc ply

我正在尝试为由分配组成的非常简单的语言生成LALR语法。例如:

foo = "bar"
bar = 42

该语言还应处理值列表,例如:

foo = 1, 2, 3

但我也希望在多行上处理列表:

foo = 1, 2
      3, 4

尾随逗号(单身人士和语言灵活性):

foo = 1,
foo = 1, 2,

显然,两者同时出现:

foo = 1,
      2,
      3,

我能用逗号或多行列表写一个语法,但不能同时写两个。

我的语法看起来像这样:

content : content '\n'
        : content assignment
        | <empty>

assignment : NAME '=' value
           | NAME '=' list

value : TEXT
      | NUMBER

list : ???

注意:我需要语法中的'\ n'来禁止这种代码:

foo
=
"bar"

先谢谢,

安托。

2 个答案:

答案 0 :(得分:2)

看起来您的配置语言基本上是免费的。我会忘记将换行符作为语法中的标记。如果你想要新行限制,你可以将其作为一些词法搭配规则进行破解,解析器调用一个添加到词法分析器的小API来告诉词法分析器它在语法中的位置,词法分析器可以决定是否接受换行或拒绝它们。

试试这个语法。

%token NAME NUMBER TEXT

%%

config_file : assignments
            | /* empty */
            ;

assignments : assignment
            | assignments assignment
            ;

assignment : NAME '=' values comma_opt

comma_opt : ',' | /* empty */;

values : value
       | values ',' value
       ;

value : NUMBER | TEXT ;

它为我构建而没有冲突。我没有运行它,但随便阅读y.output看起来过渡是理智的。

这个语法当然允许

foo = 1, 2, 3, bar = 4, 5, 6 xyzzy = 7 answer = 42

没有与词法分析者的额外沟通。

您的限制意味着只允许在值中使用换行符。两个NAME标记必须永远不会出现在同一行上,并且=必须与前一个NAME出现在同一行(并且可能还必须是第一个值)。

基本上,当解析器扫描第一个值时,它可以告诉词法分析器“现在正在扫描值,打开换行符”。然后当comma_opt减少时,可以再次关闭它。当comma_opt减少时,词法分析者可能已经读取了下一个赋值的NAME标记,但它可以检查这是否发生在与前一个NAME不同的行上。无论如何,您都希望词法分析器能够跟踪准确的行数。

答案 1 :(得分:0)

我对此并没有多少经验,但这会有效吗?

listvalue : value ,
          | value '\n'
          | value , '\n'

list : listvalue list