0

次のように、数値と文字列を含む構文を作成しようとしています。

日付: 2013 年 3 月 2 日

多かれ少なかれこれに対応する一連のルールを作成しました。

Date:
     'Date': DAY Month YEAR
;

terminal DAY:
     ('1'..'9') | (('1'..'3')('0'..'9'))
;

Month:
     name = ('Jan'|'Feb'|'Mar'|'Apr)
;

terminal YEAR
     ('0'..'2)('0'..'9')('0'..'9')('0'..'9')
;

この一連のルールには、いくつかの問題があるようです。

  1. 書かれているように、日付ルールはエラーを生成するようです:「ルール内でタイプを2回変更することはできません」。それが何を意味するのか私にはわかりませんが、Xtext では数値と​​選択文字列を同じルールで許可しないようです。

  2. Date から Month ルールを削除すると、Xtext はコンパイルされますが、構文が正しく動作しないようです。DAY ルールは、1 から 9 までの 1 桁の数字と 2 桁の数字のどちらかを選択できるはずですが、何らかの理由で 2 桁の数字しか受け付けません。したがって、次のような行を入力できますが、

日付: 2013 年 12 月 12 日

は受け入れられますが、次のような日付です:

日付: 2013 年 2 月

ではありません。

ターミナル ルールの数字を壊すルールのバグを見つけましたか? または、「|」を無視する原因となる何かが欠けていますか? 私の数では?また、「ルール内でタイプを2回変更できません」というエラーは一体何を意味し、どうすれば修正できますか???

誰かアドバイスください。

4

1 に答える 1

1

ここに設計上の問題があります。通常、カスタム端末はできるだけ使用しないでください。カスタム ターミナルは文法にグローバルな影響を与え、構文の柔軟性を低下させ、エラー リカバリの効率を低下させます。

私はあなたの意図を理解しています.DSLを制約して、無意味なデータが解析されないようにしたい. これは良い考えですが、カスタム端末はこの種のタスク用に設計されていません。経験則は次のとおりです。

  • できるだけ多くの標準端末を使用する
  • レクサーがほぼすべての入力を解析するようにする
  • パーサーに構文エラー (']' の欠落など) を検出させますが、(1 <= Day <= 31) などのドメイン制約は検出させません。
  • ドメインの制約を確認し、ユーザーにわかりやすいエラー メッセージと警告メッセージを提供するための検証を追加します。
  • クイックフィックスを追加
  • ドメインの制約に合わせてコンテンツ アシスタントを調整する

あなたのシナリオでは、次の簡単な文法を提案します。

Date:
    'Date': day=INT month=Month year=INT
;

enum Month:
    JANUARY='Jan'
|   FEBRUARY='Feb'
|   MARCH='Mar'
|   APRIL='Apr'
;

日と年が許可された範囲内にあるかどうかを確認するカスタムバリデーターを実装するよりも。ここにドキュメントがあります。その方法は次のとおりです。

于 2013-03-18T10:44:26.183 に答える