2

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エラーであることが判明しました。それを修正すると、解析は期待どおりに機能しました。FailedSemanticsvar_or_param

これは疑問を投げかけます:FailedSemantics解析ロジックに影響を与える場合、セマンティック エラーがある場合にユーザーに警告する適切な方法は何ですか?ただし、解析ロジックはそれ以外の場合は正しく、別の選択やルールを試みる必要はありません。たとえば、型の不一致や宣言前の変数の使用法は? (理想的には、エラーが発生した行番号を引き続き表示する方法で。)

4

1 に答える 1