lexer/tokenizer を構築するとき、isdigit/isalpha/... などの( Cの)関数に依存するのは間違いですか? 私の知る限り、それらはロケールに依存しています。文字セットを選択してそれに集中し、自分で文字マッピングを作成してから分類を検索する必要がありますか? 次に問題は、複数の文字セットを lex できるようになることです。文字セットごとに 1 つのレクサー/トークナイザーを作成するか、それとも、文字マッピングを変更するだけで済むように、作成したものをコーディングしようとしますか? 一般的な慣行とは何ですか?
4 に答える
今のところ、最初に単純な ASCII 文字セットを使用してレクサーを機能させることに集中します。次に、レクサーが機能しているときに、UTF-16 やロケール サポートなどのさまざまな文字タイプのマッピング サポートを組み込みます。
isdigit
いいえ、などの ctype の関数に依存することは間違いではありませんisalpha
...
実際には、おそらく後の段階で、ワイド文字 ' wctype.h 'の ctype に相当する Posix があるため、後でマクロを定義することが最善の利益になる可能性があります...透過的に変更できるようにするためさまざまなロケール セットを処理するコード...
#ifdef LEX_WIDECHARS #include <wctype.h> #define isdigit iswdigit #そうしないと #define isdigit #endif
その文脈ではそのようなものが定義されるでしょう...
これがお役に立てば幸いです。よろしくお願いします、トム。
ローカルのセンシティブなパーサーを構築しようとしても、たいしたことはできないでしょう。気が狂ってしまうでしょう。ASCII は、ほとんどの解析ニーズに対してうまく機能します -- 戦わないでください :D
それと戦って文字の分類のいくつかを使用したい場合は、Unicode を宗教的に実装するICUライブラリに目を向ける必要があります。
ctype.h 関数は、ASCII 以外を含む char にはあまり使用できません。デフォルトのロケールはC
(ほとんどのマシンで基本的に ASCII と同じです)、システム ロケールが何であるかに関係ありません。使用setlocale
してロケールを変更したとしても、システムが 8 ビット文字 (UTF-8 など) を超える文字セットを使用している可能性があります。
ワイド文字は、より多くのケースを適切に処理しますが、失敗する頻度が高すぎます。
したがって、ASCII 以外の isspace を確実にサポートしたい場合は、自分で行う必要があります (または既存のライブラリを使用する可能性があります)。
注: ASCII には文字コード 0 ~ 127 (または 32 ~ 127) しかありません。8 ビット ASCII と呼ばれるものは、実際には他の文字セットです (通常は CP437、CP1252、ISO-8859-1 など)。
一般的に、次のことを自問する必要があります。
- 正確に何をしたいのですか、どのような解析をしますか?
- どの言語をサポートしたいですか? 広範囲または西ヨーロッパのみですか?
- UTF-8 またはローカライズされた 8 ビット エンコーディングのどちらを使用しますか?
- どのOSを使用していますか?
ローカライズされた 8 ビット エンコーディングで西洋言語を使用している場合は、おそらくそうです。ロケールがインストールおよび構成されていれば、is* をリレーできます。
でも:
- UTF-8 を使用する場合は、ASCII のみがカバーされるため、できません。ASCII の外側はすべて 1 バイト以上かかるため、できません。
- 東洋の言語をサポートしたい場合は、中国語が単語を区切るためにスペースを使用しないように、構文解析に関するすべての仮定が間違っている可能性があります。ほとんどの言語には、大文字も小文字もありません。ヘブライ語やアラビア語のようなアルファベットに基づくものですらありません。
それで、あなたは正確に何をしたいですか?
さまざまなブレーク イテレータを備えた ICU ライブラリや、基本的な境界分析を提供する Qt などのツールキットを確認することをお勧めします。