あなたの質問は少し広範であるだけでなく、受け取ったコメントに示されているように、多少あいまいです。しかし、私はあなたが必要とするものが尋ねていることを理解していると思います。最初に私はあいまいさに取り組み、あなたが望むものを達成する方法を説明するつもりです。
あなたが見落としているように見えるのは、lexとyaccに関する特別なことがないことです。これらは、コンパイラで構築された通常の方法で実行されるC(またはC++)のプログラムを作成する単なるツールです。これらのプログラムによって生成された出力は、lexまたはyaccではなく、その言語のコード内の通常の入出力文によって生成されます。 Lexとyaccは、入力の認識を許可するツールであり、指定したルールに従って構造化されています。 flexとbisonツールは、多くの人が使用するこれらのツールのアナログ実装です。以下の説明ではflexとbisonを使用しますが、答えはlexとyaccに対しても同様に有効です。
lexとyaccの2つの出力ファイルについて質問すると、生成するコードファイルについて質問していると解釈できます。 lexツールは、入力ルールからlex.yy.cというファイルを生成します。このファイルには、字句解析ツールを構築するために必要なコードが含まれています。また、ヘッダファイルを出力することもできます。それはあなたがについて尋ねたものではありません、
flex --header-file=css.h --output-file=css.lex.c css.l
しかし、我々は今、知っている:だから我々はこのように、フレックスから2つのファイルを生成することができます。
バイソン/ yaccのツールは、このように、複数の出力ファイルを生成するためのいくつかのオプションがあります:
bison --defines=css-defines.h --output=css-tab.c --graph=css-graph.txt --xml=css-graph.xml css.y
をしかし、また、私たちは今、それはあなたがどちらかについて尋ねたものではありません知っています!
次の2つのファイル、CSSと1つの入力ファイルから他のHTMLを含むものを作成するプログラムを作る方法を知りたいと思いました。さまざまな出力ファイルを作成するステートメントは、Cと書かれています。我々は、2つの異なった名前の出力ファイル我々はfprintf
ステートメントを使用することができます作成することを見つけることができますC言語にa basic tutorialコンサルティング:
FILE css, html;
open(css, "file.css", "w");
open(html, "file.html", "w");
fprintf(css, "%s\n", "a:link { color:blue }");
fprintf(html, "%s\n", "<a href=\"https://stackoverflow.com/questions/37127386/\">here</a>");
fclose(css);
fclose(html);
ここ
我々はlexとyaccのツールを使用せずに2つのファイルを書かれているが、これはあなたが求めたものではなく、解決の一部です。
CSSコンポーネントとHTMLコンポーネントの両方を含む(HTML)入力ファイルを処理する場合は、どのパートがどのようなものであるかを判断するルールが必要です。これは、HTML内の<style>
タグによって決まります。最初のタスクは、これらのコンポーネントを一連のレックス規則で記述することです。オープニング<style>
と一致する閉じる</style>
を認識する必要があります。他のすべてはただの文字列として一致させることができる。
%{
#ifdef PRINT
#define TOKEN(name) printf("Token: " #name " \"%s\"\n",yytext)
#else
#define TOKEN(name) yylval.sval=strdup(yytext); return(name)
#endif
%}
%s STYLECHARS
%%
<INITIAL>\<style[^>]*> BEGIN(STYLECHARS);TOKEN(STYLE);
<STYLECHARS>"</style>" BEGIN(INITIAL);TOKEN(ELYTS);
<STYLECHARS>(.|\n|\r) TOKEN(CHAR);
<INITIAL>(.|\n|\r) TOKEN(CHAR);
これは(ウィンドウを使用して、Linuxの/ MACも同様ですが、^ DはEOFである)以下の方法で試験することができます。
flex css.l
gcc -o css.exe -DPRINT css.l -lfl
.\css
<html>
<style> a:link { color:blue } </style>
<a href=\"https://stackoverflow.com/questions/37127386/\">here</a>
</html>
^Z
テストでは、CSSセクションの開始端のタグを認識していることが示されています。
我々は今のlexからこれら
トークンが認識され、二つの出力ファイルに分割する方法を示してyacc/bisonのための一連のルールを作成することができます
:STYLEトークンを認識することで、
%{
#include <stdio.h>
#include <strings.h>
FILE *current;
%}
%union {
char *sval;
}
%token<sval> STYLE ELYTS CHAR
%%
content: stuff
| content stuff
;
stuff: chars
| styles
;
chars: CHAR {fprintf(current,"%s",$1);}
;
styles: style content elyts
;
style : STYLE { current=stderr; }
;
elyts : ELYTS { current=stdout; }
;
%%
int main (void)
{
#if YYDEBUG==1
extern int yydebug; yydebug = 1;
#endif
current = stdout;
return yyparse();
}
int yyerror (char *s)
{
printf("-%s at %s !\n",s);
}
#include "lex.yy.c"
これを出力をCSSファイルに切り替え、スタイルセクションの最後にHTMLファイルに切り替えます。これら2つのファイルにはstderr
とstdout
を使用しています。
これは、構築されたので、実行することができます:
flex css.l
bison css.y
gcc -o css.exe css.tab.c -lfl
.\css < SO.htm
をし、次のように生成します。
<html>
a:link { color:blue }
<a href=\"https://stackoverflow.com/questions/37127386/\">here</a>
</html>
私たちは、このようにCSSとHTMLを分離することができます:
.\css <SO.htm> SO-html.txt 2> SO-css.txt
をこれが可能ファイル名を引数として受け入れ、出力用の名前付きファイルを生成するツールを作成するようにさらに修正されました。あなたが尋ねたこと。
が広すぎると思われるかもしれませんが、少しチュートリアルが役立つことを願っています。
2つの異なるパーサーを作成する必要がありますか?または、入力を処理する過程で、さまざまな出力ファイルが生成されますか? – rici
1つのlexファイルと1つのyaccファイルが2つの出力ファイルを生成します。 – Leon
* lex *は1つの出力ファイルを生成し、* yacc *は選択するオプションに応じて1,2、または3を生成できます:.c、.h、および名前がすべての状態情報を含むのを忘れたもう1つ。 *生成コード*で複数の出力ファイルを生成したい場合は、必要なコードを記述するだけです。あなたが何を求めているのか不明です。 – EJP