解析正确时如何处理 TatSu 中的语义错误?

How to handle semantic failures in TatSu when parsing is correct?

我正在尝试为包含类 C 表达式的语言创建 TatSu 解析器。我对表达式有以下语法规则:

identifier =
    /[a-zA-Z][A-Za-z0-9_]*/
    ;

expression =
    or_expr
    ;

or_expr =
    '||'<{and_expr}+
    ;

and_expr =
    '&&'<{bitwise_or_expr}+
    ;

bitwise_or_expr =
    '|'<{bitwise_xor_expr}+
    ;

bitwise_xor_expr =
    '^'<{bitwise_and_expr}+
    ;

bitwise_and_expr =
    '&'<{equality_expr}+
    ;

equality_expr =
    ('==' | '!=')<{comparison_expr}+
    ;

comparison_expr =
    ('<' | '<=' | '>' | '>=')<{bitshift_expr}+
    ;

bitshift_expr =
    ('<<' | '>>')<{additive_expr}+
    ;

additive_expr =
    ('+' | '-')<{multiplicative_expr}+
    ;

multiplicative_expr =
    ('*' | '/' | '%')<{unary_expr}+
    ;

unary_expr =
    '+' ~ atom
    | '-' ~ atom
    | '~' ~ atom
    | '!' ~ atom
    | atom
    ;

atom =
    literal
    | helper_call
    | parenthesized
    | var_or_param
    ;

literal =
    value:float type:`float`
    | value:integer type:`int`
    | value:char type:`char`
    | value:string type:`string`
    | value:bool type:`int`
    | value:null type:`null`
    ;

helper_call =
    function:identifier '(' ~ params:expression_list ')'
    ;

var_or_param =
    identifier
    ;

parenthesized =
    '(' ~ @:expression ')'
    ;

我 运行 遇到了 atom 规则的麻烦。解析以下内容时(expression=; 之间的部分):

lastTime = ts + interval;

我遇到了这个异常:

tatsu.exceptions.FailedToken: (27:41) expecting '(' :
                lastTime = ts + interval;
                                        ^
helper_call
atom
unary_expr
multiplicative_expr
...

尝试使其符合 helper_call 规则失败,而 var_or_param 规则本应匹配得很好。事实证明,原因是 var_or_param 的语义操作引发了错误的 FailedSemantics。一旦我解决了这个问题,解析就按预期工作了。

这提出了一个问题:如果 FailedSemantics 影响解析逻辑,当存在语义错误时提醒用户的正确方法是什么,但解析逻辑在其他方面是正确的,不应尝试不同的选择或规则?例如,声明前的类型不匹配或变量使用? (理想情况下,仍会显示发生错误的行号。)

FailedSemantics 确实会影响解析。它在解析逻辑中被翻译成 FailedParse

如果解析应该停止,则继续使用 FailedSemantics

在其他情况下由您决定。

TatSu 的设计使得大部分语义检查在解析成功后通过 walker 或其他方式完成。