bison/yacc 语法消歧

发布于 2024-11-09 08:33:55 字数 809 浏览 7 评论 0原文

我有以下野牛语法(作为更复杂语法的一部分): <代码>

expression:
    IDENTIFIER
    | CONST
    | LAMBDA match_block
;
match_block:
    pattern '=' expression
    | match_block '|' pattern '=' expression
;
pattern:
    IDENTIFIER
    | CONST
;
which describe expressions containing identifiers, constants and lambda-functions with pattern matching, which looks like this:
lambda 0 = 1
     | 1 = 2
     | x = x
Problem is 1 shift/reduce conflict caused by ambiguity with nested matches, as in following example:
lambda 0 = 1
     | x = lambda 1 = 2
                | y = 4
Rule is that match block relate to closest function, as shown with indentation in example above.

我的问题是 - 如何重写这个语法来消除这种歧义(不使用 %left %right yacc 指令)?

I have following bison grammar (as part of more complex grammar):

expression:
    IDENTIFIER
    | CONST
    | LAMBDA match_block
;
match_block:
    pattern '=' expression
    | match_block '|' pattern '=' expression
;
pattern:
    IDENTIFIER
    | CONST
;


which describe expressions containing identifiers, constants and lambda-functions with pattern matching, which looks like this:

lambda 0 = 1
     | 1 = 2
     | x = x


Problem is 1 shift/reduce conflict caused by ambiguity with nested matches, as in following example:

lambda 0 = 1
     | x = lambda 1 = 2
                | y = 4


Rule is that match block relate to closest function, as shown with indentation in example above.

My questions is - how can I rewrite this grammar to eliminate this ambiguity (without using %left %right yacc directives)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

若沐 2024-11-16 08:33:55

如果您始终希望 | 绑定到最近的 LAMBDA,那基本上意味着您只能在 LAST 中拥有 LAMBDA match_block 的 >| 子句:

non_lambda_expression:
    IDENTIFIER
    | CONST
;
expression:
    non_lambda_expression
    | LAMBDA match_block
;
non_lambda_match_block:
    pattern '=' non_lambda_expression
    | non_lambda_match_block '|' pattern '=' non_lambda_expression
;
match_block:
    pattern '=' expression
    | non_lambda_match_block '|' pattern '=' expression
;
pattern:
    IDENTIFIER
    | CONST
;

基本上,您将 expressionmatch_block 分成两个版本 - 一个允许 lambda,另一个允许 lambda不是这样的——并在每个地方使用适当的一个以避免歧义。

If you always want the | to bind to the closest LAMBDA, that basically just means that you can only have a LAMBDA in the LAST | clause of a match_block:

non_lambda_expression:
    IDENTIFIER
    | CONST
;
expression:
    non_lambda_expression
    | LAMBDA match_block
;
non_lambda_match_block:
    pattern '=' non_lambda_expression
    | non_lambda_match_block '|' pattern '=' non_lambda_expression
;
match_block:
    pattern '=' expression
    | non_lambda_match_block '|' pattern '=' expression
;
pattern:
    IDENTIFIER
    | CONST
;

Basically, you split expression and match_block into two versions -- one that allows lambdas and one that does not -- and use the appropriate one in each spot to avoid the ambiguity.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文