パーサーは複雑である必要はない——bx::Scannerが示す新しい道
Parsers don't have to be complicated

bgfxの開発者であるBranimir Karadžićは、パーサー生成ツールやアドホックな手書きパーサーに代わる、シンプルで再利用可能なスキャナー「bx::Scanner」を紹介します。ゼロコピーでアロケーションフリー、行・列の追跡、文字クラスによる直感的なAPIを備え、INIパーサーやURL解析、パス正規化、スタックトレースのシンボル化などに応用。パーサーは複雑でなくてよいという主張を、実例とともに示します。
パーサーは本当に複雑である必要はない。
- imoverclocked
パーサーを書く上で最も難しいのは、何を有効な入力と見なすかを認知的に受け入れることだ。高速で仕様が明確な最高のパーサーを作っても、誰かが必ず予期しない方法で(悪用)するものだ。
有名な例:当初は多くの良い意図があったにもかかわらず、HTMLタグは閉じる必要がなく、JSONの数値は文字列としてエンコードされることがあまりにも多く、YAMLは多くの人が期待するように見えることもあれば、ますますJSONのように見えることもある…そしてそれは続く。
- zabzonk
FORTHのパーサーは超シンプルだ。スペースで区切られた次のトークンを取得し、それが数値ならスタックにプッシュし、そうでなければワードとして辞書で調べ、(存在すれば)実行する。
- f311a
残念ながら、単純なURLパーサーは多くの点で壊れてしまう。すべてのURLパースライブラリが少なくとも数千行のコードになるのには理由がある。
よくあるテスト方法の一つは、IPv6 URLを渡すことだ: http://[f021:d981:b487:e57d:193e:550e::]/
- mrkeen
「アドホックなバイトいじりのナンセンス」から「パーサーコンビネータ」まで線を引くと、これは20%も進んでいない。
リンク先のURLパーサーを見ると、なぜ次のようになっていないのか:
url = do scheme
authority
path
query
fragment
where
scheme = ...
authority = ...
etc.
完全にアドホックに見える。
- Retr0id
> LineReaderは入力を行に分割し、\nと\r\nを処理し、不正な入力が残しがちな余分な末尾の\rをトリムする
不正な入力に余分な\rが含まれる一般的な原因は、\r\nの一部として存在するもの以外にあるのでしょうか?それとも、これは単にWindowsスタイルの改行に対する嫌味なのでしょうか?もし何か奇妙なことが起こっているなら、むしろ大声で失敗したいと思います。
> 内部スキャナーを1行に制限することで、「不正な行の終わりを超えて実行する」ことを単に起こりにくくするのではなく、表現不可能にします。
それがなぜ「表現不可能」なのか、私にはよくわかりません。これはむしろ「正しいスキャンロジックを使えば、間違ったスキャンロジックを使うことはできない」と読めます。