0

あいまいな文法に問題があります。私はこれを持っています:

%token identifier
%token lolcakes

%start program

%%

program
    : call_or_definitions;

expression
    : identifier
    | lolcakes;

expressions
    : expression
    | expressions ',' expression;

call_or_definition
    : function_call
    | function_definition;

call_or_definitions
    : call_or_definition
    | call_or_definitions call_or_definition;

function_argument_core
    : identifier
    | identifier '=' expression
    | identifier '=' '{' expressions '}';

function_call
    : expression '(' function_arguments ')' ';';

function_definition
    : identifier '(' function_definition_arguments ')' '{' '}';

function_argument
    : lolcakes
    | function_argument_core;

function_arguments
    : function_argument 
    | function_arguments ',' function_argument

function_definition_argument
    : expression function_argument_core
    | function_argument_core;

function_definition_arguments
    : function_definition_argument
    | function_definition_arguments ',' function_definition_argument;

これは私の本物の文法のサブセットであり、個別にコンパイルできます。現時点では、ストリームとの間function_callにS/Rの競合が発生します。関数呼び出しと関数定義の文法を統一することで、トークンストリームの後半まで決定を下す必要がないことをBisonに納得させようとしています。言い換えると、呼び出しと定義の両方に共通する何かに遭遇した場合、どちらがどちらであるかを知る必要なしにそれを減らすことができ、他の何かに遭遇した場合、他の何かがどちらを明確にラベル付けします。それも可能ですか?もしそうなら、どうすればそれができますか?可能であれば、入力ストリームの構造を変更する必要はありません。function_definitionidentifier (

4

2 に答える 2

1

またはidentifier ( identifierの先読みで確認するまで、問題は発生しないはずです。その時点で、パーサーは2番目の識別子をaまたは(になる)として減らすかどうかを決定する必要があります。,)function_definition_argumentexpressionfunction_argument

これは、ブルートフォースによって文法で純粋に解決できますが、expression_not_naked_identifierとのような非終端記号の迷路に導かれ、ambiguous_begining_of_function_defn_or_callセマンティックアクションの重複が横行します。

次のようなものを書くと、おそらくより保守しやすくなります(そして、よりわかりやすい構文エラーメッセージにつながります)。

definition_or_call_start: identifier '(' generic_argument_list ')'
generic_argument_list: generic_argument
                     | generic_argument_list ',' generic_argument
generic_argument: expression 
                | function_argument_core
                | ...
function_call: definition_or_call_start ';';
function_definition : definition_or_call_start '{' '}';

generic_arguments次に、最後の2つのプロダクションのアクションのセマンティック制約として、解析した実際のプロダクションが使用されている用途と一致することを確認します。

于 2011-08-11T11:43:55.707 に答える
1

問題は、expressionが単一ので構成されている可能性があることidentifierです。この時点で、パーサーはそれがidentifier唯一であるか、それをに減らすかどうかを決定する必要があります。これexpressionは、後でパスを決定するためです。

于 2011-08-11T11:46:48.093 に答える