解析正确时如何处理 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
影响解析逻辑,当存在语义错误时提醒用户的正确方法是什么,但解析逻辑在其他方面是正确的,不应尝试不同的选择或规则?例如,声明前的类型不匹配或变量使用? (理想情况下,仍会显示发生错误的行号。)
FailedSemantic
s 确实会影响解析。它在解析逻辑中被翻译成 FailedParse
。
如果解析应该停止,则继续使用 FailedSemantics
。
在其他情况下由您决定。
TatSu 的设计使得大部分语义检查在解析成功后通过 walker 或其他方式完成。
我正在尝试为包含类 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
影响解析逻辑,当存在语义错误时提醒用户的正确方法是什么,但解析逻辑在其他方面是正确的,不应尝试不同的选择或规则?例如,声明前的类型不匹配或变量使用? (理想情况下,仍会显示发生错误的行号。)
FailedSemantic
s 确实会影响解析。它在解析逻辑中被翻译成 FailedParse
。
如果解析应该停止,则继续使用 FailedSemantics
。
在其他情况下由您决定。
TatSu 的设计使得大部分语义检查在解析成功后通过 walker 或其他方式完成。