1

ユーザーに制限付きの DSL を提供するために、運用環境用のカスタム式パーサーとエバリュエーターを構築しています。DSL としてのパーサー自体は、単純である必要があります。パーサーは、動的な式の解析をサポートしておらず、パーサー ジェネレーター ツールも利用できないエキゾチックな言語で構築される予定です。

私の現在の決定は、LL(1) 文法を使用した再帰的降下法を採用することです。これにより、式を評価した経験のないプログラマーでも、コードがどのように機能するかをすぐに学ぶことができます。

小数、パーセンテージ、文字列、日付など、いくつかのデータ型で構成される混合式を処理する必要があります。また、dd/mm/yyyy 形式の日付は、一連の除算演算と混同しやすいです。

この問題の良い解決策はどこにありますか?

パーサーをシンプルに保つことを目的としており、日付に特別な記号を付けることを目的とした私自身の解決策は、アポストロフィとしましょう:

<date>   ::= <apostr><digit><digit>/<digit><digit>/<digit><digit><digit><digit>

<apostr> ::= '

<digit>  ::= '0'..'9'
4

3 に答える 3

2

無限の先読みを備えた LL のようなレクサーレス パーサーが必要です。そして、すなわちPEGです。

http://en.wikipedia.org/wiki/Parsing_expression_grammar

順序付けされた選択により、この日付と定数リテラルの除算の混乱を避けるのは非常に簡単です。

于 2010-03-17T15:01:48.673 に答える
2

まず、私は LL パーサーのファンなので、あなたのアプローチに心から賛同します。人気のある新しいパーサー ジェネレーター ( ANTLR ) の 1 つが LL であることに注意してください。LL(1) に制限するのではなく、より多くの先読みを許可する場合、LR(1) パーサーでやりたいことはほとんど何でもできますが、コードははるかに明確で信頼性が高くなります。デバッグしやすくなります。

あなたの全体的な文法について、私は判断できるほど十分に知りません。LL パーサーが整数式か日付定数かをコンテキストから常に判断できるように設計できる可能性があります。ただし、できないと仮定すると、違いを見分ける何らかの方法が必要になります。私が考えることができる唯一の他のことは、スラッシュの代わりにバックスラッシュをセパレーターとして使用することですが、それはちょっと醜いです.

于 2010-03-17T13:31:43.817 に答える
0

言語が人間の入力を意図している場合、それを定義することは、

  • 明確で簡単な解析を保証する構文制約の追加
  • 構文を削除/曲げて、意図した人間の聴衆にとって言語が直感的で「自然」に感じられるようにします。

2 番目の要件を満たすことは、最初の要件よりもはるかに難しく、

  • 言語の意図された使用例
    どのタイプのキーボード/入力デバイスが利用可能ですか? 許可された文字の中に、表示が難しい、またはディスプレイ上で見えにくい文字はありますか?
    頻繁に使用され、たまにしか必要とされないトークン/式はどれですか? ユーザーは短いアドホック コード スニペットを頻繁に入力するのか、それとも長期間にわたって再利用および変更することを意図したプログラムなのか
    ... など。
  • 対象読者の背景/文化
    可能であれば、他の通常の (そして単純な自然) 言語のどの一般的な慣行/イディオムを再利用できるか、または再利用する必要がありますか?
    簡潔だが不可解なスタイルを好むべきか、それともより明示的だがより冗長なスタイルを好むべきか?
    ...など

基本的に、言語の構文について提案することは、使用目的とユーザーを十分に把握することができずに困難です。
それにもかかわらず、日付形式の質問に対して次のことを提案したいと思います。

日付値には別の形式を使用してください。ユーザーにとって十分に「自然」でありながら、通常の文法で説明できるほど十分に特徴的なもの。
たとえば、月に 3 文字の略語を使用するもの(欠点 DSL は英語や他の言語に結び付けられますが、利点もあります。人間にとってどれが日でどれが月かという曖昧さが取り除かれます)。とりあえず:

  dd-mmm-yyyy    (may seem unnatural in cultures where the prevailing date order 
                  starts with the month maybe yyyy-mmm-dd then ?)
  mmm-dd-yyyy    (better for the above mentioned cultures)
  ddmmmyyyy      (avoid the dashes, but impose leading zeros)

  MnnDnnYyyyy    (using "M", "D" and "Y" (or others) as explicit prefixes; now, 
                  this is completely culture neutral, but maybe a bit awkward...)

とにかく、ただのアイデアです...適用可能性は、言及された人的/文化的要因、および残りの構文によって異なります。たとえば、上記は変数が明示的にマークされていることを暗示している可能性があります (たとえば、多くの言語が $ プレフィックスを使用する理由の 1 つです)。これは、[奇数だが可能性のある] 変数識別子との競合を回避するためです。

簡単に言えば、12 か月タグをパーサーにとって十分な識別子にすることで、特殊文字の接頭辞 (数学やその他の式でこれらの文字を使用すると衝突する可能性があります) の必要性を置き換えるという考えです。

于 2010-03-17T15:05:57.417 に答える