iniファイル用のパーサーを作成します。 理論

この記事は、パーサーを作成するための2つの類似ライブラリー、C ++用のBoost SpiritとHaskell用のParsecの視覚的な比較を目的としています。 それから、記事を3つの部分に分ける方が良いと判断しました。 最初の部分では、iniファイルの内容を説明するためのコンテキストフリー文法の書き方を説明します。

iniファイル


ini拡張子を持つファイルは、Windowsの世界だけでなく、他のシステム(php.iniなど)でも広く配布されています。 iniファイルの形式は非常に単純です。ファイルはセクションに分割され、各セクションには「パラメーター=値」の形式の任意の数のレコードを含めることができます。 異なるセクションのパラメーターの名前は一致できます。
[_1]
1=1
2=2

[_2]
1=1
2=2

各パラメーターは、セクション名とパラメーター名でアドレス指定できます: '_1'.'2'

Iniファイルはコメントを提供します-「;」で始まる行。

文法を構築する


このフォーマットを、 拡張バッカス-ナウア表記法の文脈自由文法として説明してみましょう(詳しくない人でも明確になることを願っています)。

iniファイルとは何かを説明しましょう。 これを行うために、最も複雑な(iniファイル自体)から最も単純な(識別子と呼ばれる)までのすべての構造を説明します。 このような各構造は、他の非終端記号と通常の記号(終端記号)によって定義される特別な指定(非終端記号)に関連付けられます。
引用符で囲みます。

一部のパーサー/ユーザーが余分なスペースと空の行を挿入することを好むことを考慮する必要があります。
これを行うには、さらに2つの非終端記号を導入する必要があります。文字列で使用される空白文字と、単なる空白文字です。
stringSpaces = {" " | "\t"} .
spaces = {" " | "\t" | "\n" | "\r"} .

スペースはほぼどこでも使用できます。 したがって、文法をわずかに修正します。
inidata = spaces, {section} .
section = "[", ident, "]", stringSpaces, "\n", {entry} .
entry = ident, stringSpaces, "=", stringSpaces, value, "\n", spaces .
ident = identChar, {identChar} .
identChar = letter | digit | "_" | "." | "," | ":" | "(" | ")" | "{" | "}" | "-" | "#" | "@" | "&" |"*" | "|" .
value = {not "\n"} .
stringSpaces = {" " | "\t"} .
spaces = {" " | "\t" | "\n" | "\r"} .


それは基本的に文法=)についてすべてです。

おそらく誰かが私がコメントについて何も言わなかったことに気づいたでしょう。 忘れませんでした-「ペン」で切り取るのが簡単です=)(演習として、文法を修正してコメントを考慮に入れることができます)。

重要:再帰を残さないように、私は少しcheし、文法を作成しました。 私が検討している両方のライブラリーは、左再帰に対して脆弱な再帰的下降パーサーを構築します。 これらのライブラリを実際のプロジェクトで使用する前に、それが何であり、どのように対処するかを理解してください=)。

これで、この文法の使用を比較して、 C ++Haskellでパーサーを構築できます。

PS。 この記事を開発ブログに投稿するアイデアをくれたmaxshopenに感謝します。

Source: https://habr.com/ru/post/J50973/


All Articles