0

書式設定言語用のコンパイラを作成しようとしています。この言語には、開始プロパティと終了プロパティ、および一連のドキュメント プロパティとテキスト プロパティがあります。1 つ目はドキュメント自体の情報ですが、2 つ目は実際のドキュメント (タイトル、段落、リストなど) です。最初のセットは、常に開始プロパティに従う必要があり、すべてのプロパティを含む必要がありますが、ユーザーが好む任意の順序である必要があります。

プロパティのトークンが PROP1、PROP2、PROP3、および PROP4 であると仮定すると、ユーザーが必要なドキュメント プロパティを定義できるように、すべてのプロパティに対して再帰と OR を使用できます。

doc_properties
    : /* empty */
    : doc_properties property  
    ;
property
    : PROP1
    : PROP2
    : PROP3
    : PROP4
    ;

しかし、どうすれば彼にそれらすべてを一度だけ定義させることができますか。私が考えた 1 つの方法 (避けたい簡単で大雑把な方法) は、4 つのドキュメント プロパティしかないため、すべての可能な組み合わせを作成できます。別の方法があると確信しています。何か助けはありますか?

これまでの私の文法はかなり単純で小さいです

%{ /* C Stuff */ %}

/* union and error stuff and tokens */

%%

source
    : /* empty */  
    | entry_point doc_properties txt_properties exit_point
    ;

entry_point
    : SLASH BLOCK_S LBRACE DOC RBRACE 
    ;

doc_properties 
    : /* This is where my question goes */  
    ;

txt_properties
    : /* empty */  
    ;

exit_point
    : SLASH BLOCK_E LBRACE DOC RBRACE
    ;


%%

int main (int argc, char* argv[])
{
    /* various checks for the arguments and the input output files */

        yyin = fopen(argv[1], "r");
        yyout = fopen(fn, "w");     
        //do{
            yyparse();
        //}while(!feof(yyin));
        fclose(yyin);
        fclose(yyout);

    return 0;
}

void yyerror(const char* str) {
    fprintf(stderr,"syntax error[%d]: %s\n",yylineno, str);
}

また、無関係な注意事項として、do-while ループ内で yyparse() を使用するか、それ自体で 1 回だけ使用すると、何か違いがありますか? 私はそれを両方の方法で見ており、do-while ループがより理にかなっている間 (トークンの解析を要求してからもう一度行うため)、関数がそれ自体を繰り返すか何かを繰り返すかはわかりません...

4

1 に答える 1

3

文法自体ではなく、セマンティック チェックによって適用されるのが最適な構文規則がいくつかあります。たとえば、C のような言語では、break構文はループ (およびスイッチ) 内にのみ表示できますが、通常のステートメントのように受け入れる方がはるかに簡単で、後で意味解析パスで無効な使用を拒否しますbreak

同様のパターンを使用できます: の任意の組み合わせを受け入れPROP、後で制約を尊重しないものを拒否します。もちろん、解析中にこれを行うこともでき、必要YYERRORに応じてエラーを発生させるために使用できます。

2 番目の質問にyyparseは、1 回だけ呼び出されることになっていますが、もちろん、スキャナー ( yylex) を繰り返し呼び出すことを担当しています。Bison は「プッシュ パーサー」を提供していることに注意してください。ここで、繰り返し呼び出しを担当し、yylexその結果をyyparse(繰り返し) に渡します。詳細については、 http://www.gnu.org/software/bison/manual/bison.html#Push-Declを参照してください。

于 2012-12-09T13:58:36.620 に答える