書式設定言語用のコンパイラを作成しようとしています。この言語には、開始プロパティと終了プロパティ、および一連のドキュメント プロパティとテキスト プロパティがあります。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 ループがより理にかなっている間 (トークンの解析を要求してからもう一度行うため)、関数がそれ自体を繰り返すか何かを繰り返すかはわかりません...