如何提高 Antlr4 解析器分支的优先级?

问题描述 投票:0回答:1

我创建了以下语法:

grammar Test;

COMMA: ',';
OPEN: '(';
CLOSE: ')';

ATOM: [0-9a-zA-Z_]+;
SPACE: [ \r\n\t]+ -> skip;

start: expr EOF;

expr
    : ATOM                                         # Identifier
    | expr OPEN (expr (COMMA expr)*)? CLOSE        # Call
    | OPEN expr CLOSE                              # Wrap
    | expr COMMA expr                              # Then
    ;

然后我尝试解析

FUNC(1, (2, 3), 4)

但它给了我这个结果

start:
    expr:
        expr "FUNC"
        "("
        expr:
            expr:
                expr "1"
                ","
                expr:
                    "("
                    expr:
                        expr "2"
                        ","
                        expr "3"
                    ")"
            ","
            expr "4"
        ")"
    <EOF>

而不是

start:
    expr:
        expr "FUNC"
        "("
        expr "1"
        ","
        expr:
            "("
            expr:
                expr "2"
                ","
                expr "3"
            ")"
        ","
        expr "4"
        ")"
    <EOF>

如何使解析器更喜欢

Call
分支而不是
Then
分支? (我感觉Antlr4中的*更像正则表达式中的*?,是真的吗?)

parsing antlr4 operator-precedence antlr4cs
1个回答
0
投票

我最终完全消除了歧义:

  • 我允许
    Then
    分支有N个表达式
  • 我创建了一个名为
    block
    的新解析器节点,它将表示多个表达式序列
  • 我删除了
    Then
    分支,因为它现在由
    block
  • 表示
  • 我明确指定了表达式内部允许使用
    block
    的位置
grammar Test;

COMMA: ',';
OPEN: '(';
CLOSE: ')';

ATOM: [0-9a-zA-Z_]+;
SPACE: [ \r\n\t]+ -> skip;

start: block EOF;

block: expr (COMMA expr)*;

expr
    : ATOM                      # Identifier
    | expr OPEN block? CLOSE    # Call
    | OPEN block CLOSE          # Wrap
    ;
© www.soinside.com 2019 - 2024. All rights reserved.