nDiki : 1999年01月31日

1999年1月31日 (日)

flex文法定義を読む(定義節/parse.y)

字句解析系生成プログラム作成のために、flex-2.5.4a.tar.gzの文法定義を読んでみる。 まずここでは、定義節(definitions section)を読むことにする。

トークンの定義は scan.l で、構文の定義は parse.y でなされている。 まずは parse.y から見ていこう。 以下の引用部はすべて parse.y である。 行頭には行番号を付加してある。 また説明に不要な部分は省略してある。

以下はでのトークン名の宣言である。

     3	%token CHAR NUMBER SECTEND SCDECL XSCDECL NAME PREVCCL EOF_OP
     4	%token OPTION_OP OPT_OUTFILE OPT_PREFIX OPT_YYCLASS
     5
     6	%token CCE_ALNUM CCE_ALPHA CCE_BLANK CCE_CNTRL CCE_DIGIT CCE_GRAPH
     7	%token CCE_LOWER CCE_PRINT CCE_PUNCT CCE_SPACE CCE_UPPER CCE_XDIGIT

また以下は定義節に関係するルールの部分である。

   112	goal		:  initlex sect1 sect1end sect2 initforrule
   139			;
   141	initlex		:
   147			;
   149	sect1		:  sect1 startconddecl namelist1
   150			|  sect1 options
   151			|
   152			|  error
   154			;
   156	sect1end	:  SECTEND
   162			;
   164	startconddecl	:  SCDECL
   167			|  XSCDECL
   169			;
   171	namelist1	:  namelist1 NAME
   174			|  NAME
   177			|  error
   179			;
   181	options		:  OPTION_OP optionlist
   182			;
   183
   184	optionlist	:  optionlist option
   185			|
   186			;
   188	option		:  OPT_OUTFILE '=' NAME
   193			|  OPT_PREFIX '=' NAME
   195			|  OPT_YYCLASS '=' NAME
   197			;

goal (112行目)は開始記号である。 ここで字句解析仕様記述全体の構造を定義している。 ここでは sect1end までを見ることにする。

   141	initlex		:
   147			;

initlex (141行目)は仕様記述の先頭の部分で還元される。 ここで初期化処理が行われる。

   156	sect1end	:  SECTEND
   162			;

sect1end (156行目)トークン SECTEND を導出する。

 SECTEND は scan.l119行目の

^"%%".* のパターンで定義されるものである。 つまり、行頭の %% で 定義節が終了することを示す。

   149	sect1		:  sect1 startconddecl namelist1
   150			|  sect1 options
   151			|
   152			|  error
   154			;

定義節の中身は sect1によって導出される。 定義節は、開始条件の宣言(startconddecl namelist1 または オプション指令options の任意個の繰り返しを導出する。

   164	startconddecl	:  SCDECL
   167			|  XSCDECL
   169			;

startconddecl はトークン SCDECL または XSCDECL である。 SCDECL は scan.l108行目の ^"%s"{NAME}? で定義され、XSCDECLは109行目の ^"%x"{NAME}? である。 よって行頭から始まる %s または %x (名前として使える文字列が続いてもよい)によって始まる行が開始条件の宣言ということになる。

   171	namelist1	:  namelist1 NAME
   174			|  NAME
   177			|  error
   179			;

SCDECL または XSCDECL の次には namelist1 が次に導出される。 namelist、トークン NAME の1回以上の繰り返しである。

   181	options		:  OPTION_OP optionlist
   182			;

一方 sect1 は options も導出する。 options は、トークンOPTION_OP の後に optionlistが続くとなっている。 OPTION_OP は scan.l131行目にある ^"%option" にマッチした時返されるトークンである。 つまりオプション指令は行頭から始まる %option によって始まることを示している。

   184	optionlist	:  optionlist option
   185			|
   186			;

そして optionlist(181行目) は option の 0回以上の繰り返しである。

   188	option		:  OPT_OUTFILE '=' NAME
   193			|  OPT_PREFIX '=' NAME
   195			|  OPT_YYCLASS '=' NAME
   197			;

その option は トークンOPT_OUTFILE, OPT_PREFIX, OPT_YYCLASS のどれかの後に '=' が続き、そしてその後に NAME がくるといいうものである。OPT_OUTFILE, OPT_PREFIX, OPT_YYCLASS はそれぞれ文字列 outfile, prefix, yyclass が対応する。

これだけでは定義節のすべての文法を網羅していない。実は他の多くの部分は、字句解析で処理してしまっている。次回はscan.l についてもうすこし詳しく見てみよう。

スポンサード リンク

本日誌ページ用 m4 マクロを作成

本日誌を始めて、13日目。やっと本日誌ページ用 m4 マクロを作成した。

私の Web ページ (http://www.j.dendai.ac.jp/~naney/以下) はm4 を利用して作成している。 m4 はマクロプロセッサである。 主に何に利用しているかというと、ヘッダやフッタなどの定型的な部分の生成などである。 ヘッダやフッタなどをマクロ化し、各ページでパラメータを指定して展開させることで、それぞれにあったものを生成する。 利点としては、例えばヘッダの形式を変えたい場合にマクロを書き換えることで、全ページを変更することができることなどがある。 SSI による include では各ページ固有の情報などのパラメータ部分がうまく扱えない。 ちなみに m4 ページの処理は、AutoconfAutomake を利用して、./configure; make; make install; で一発で済むようにしている。

前置きがながくなった。もちろんこのページのヘッダやフッタなどもマクロ展開で行っていたのだが、ナビゲーションの [Prev Day]、 [Next Day] などは毎日手でリンクを張っていた(実際には前日のものをコピーして書き換え)。 これは面倒だし、間違えもおきやすいので、この部分を処理するマクロを本日作成した。 まだあまりチェックしていないので、もしかしたらうまくリンクがつながらないかもしれない。

次はキーワードインデックス部分と、記事別ナビゲーション(似ている内容の記事ごとの、Prev、Next のリンク) の生成を自動化したいが、これは m4 だけではかなり辛いか(できるとは思うが)。

[ 1月31日全て ]

About Me

Naney Naney (なにい)です。株式会社ミクシィで SNS 事業の部長をしています。

nDiki1999年1月に始めたコンピュータ日誌を前身とする NaneyWeb 日記(兼パーソナルナレッジベース)です。ちょっとしたノートは nNote にあります。

※内容は個人的見解であり所属組織とは関係ありません。

follow us in feedly

月別インデックス
Process Time: 0.04601s / load averages: 0.17, 0.36, 0.42
nDiki by WATANABE Yoshimasa (Naney, Google profile)
Powered by DiKicker