0

我正在使用来自 lark-parser 库的 LALR(1) 解析。我写了一个语法来解析类似 ORM 的语言。我的语言示例粘贴在下面:

Table1
.join(table=Table2, left_on=[column1], right_on=[column_2])
.group_by(col=[column1], agg=[sum])
.join(table=Table3, left_on=[column1], right_on=[column_3])
.some_column

我的语法是:

start: [CNAME (object)*]
object: "." (CNAME|operation)
operation: [(join|group) (object)*]

join: "join" "(" [(join_args ",")* join_args] ")"
join_args: "table" "=" CNAME
         | "left_on" "=" list
         | "right_on" "=" list

group: "group_by" "(" [(group_args ",")* group_args] ")"
group_args: "col" "=" list
          | "agg" "=" list 

list: "[" [CNAME ("," CNAME)*] "]"

%import common.CNAME     //# Variable name declaration
%import common.WS        //# White space declaration
%ignore WS

当我解析语言时,它会被正确解析,但我会收到 shift-reduce 冲突警告。我相信这是由于在 处发生碰撞object: "." (CNAME|operation),但我可能错了。有没有其他方法可以写这个语法?

4

1 回答 1

2

我认为你应该更换

operation: [(join|group) (object)*]

只需

operation: join | group

您已经允许重复objectin

start: [CNAME (object)*]

object*所以最后也允许operation是模棱两可的,导致冲突。

就个人而言,我会选择类似的东西:

start    : [ CNAME ("." qualifier)* ]
qualifier: CNAME | join | group

因为我看不到object. 但这只是风格上的细微差别。

于 2019-08-23T05:48:30.237 回答