2017-02-11 13 views
2

入力からのForth形式のスキップを希望します.Forth形式は、入力がすべてifで始まり、thenで終わる場合、すべての入力が正しい不一致処理を必要としないと仮定します。赤色の再帰的な構文解析

問題は、ifの各部分は、他の任意の数を再帰的に含むことができますifのです。ここで

は、テストケースで私の最高のソリューションです:

Red [] 

skip-nested-ifs: [skip to ['if | 'then] skip-nested-ifs-helper] 
skip-nested-ifs-helper: ['then | skip-nested-ifs skip-nested-ifs-helper ] 


rules: skip-nested-ifs 

test-cases: [ 
    [if a then] 
    [if a else b then] 
    [if a if b then then] 
    [if a if b then 5 then] 
    [if a if b then 5 if c then then] 
    [if a else if b then then] 
    [if a else if b then 5 then] 
    [if a else if b then if c then then] 
    [if a if b if c then if d then then then] 
] 

forall test-cases [ 
    prin [mold test-cases/1 ""] 
    print either parse test-cases/1 rules [ "OK" ] [ "FAIL" ] 
] 

出力は次のとおりです。

[if a then] OK 
[if a else b then] OK 
[if a if b then then] OK 
[if a if b then 5 then] FAIL 
[if a if b then 5 if c then then] FAIL 
[if a else if b then then] OK 
[if a else if b then 5 then] FAIL 
[if a else if b then if c then then] OK 
[if a if b if c then if d then then then] OK 

彼らは1 thenとの間で何か(この場合は5)が含まれているためので、それらの3が失敗します別の

おそらく、修正は非常に簡単で明白ですが、今は表示されません。可能であれば、上記のルールを修正したり、すべてのテストに合格する別のルールを表示したりできますか?

+0

最初のルールで 'to'を使用していますか、本当に' thru'を本当に使いたいですか? – DocKimbel

+0

'parse-trace'は解析をデバッグするのに便利です –

+0

@DocKimbel私は' then'を最初に見つけたので 'to'を意図的に使用しています - これは現在の' if'が終了したことを意味します。 1。 – user3033648

答えて

5

ルールが修正可能かどうかは、再帰に大きく依存していますが、テスト#5に必要な繰り返しサポートを提供できないため、ルールが修正可能かどうかはわかりません。 skipは端末トークンと非終端トークンの両方を消費するため(ifを含む)、それを修正することができませんでした。

私は別の解決策を考え出しました。それは長いですが、(レッドを使用して)すべてのテストに合格:

rules: [ 
    'if skip 
    opt ['else [some rules | skip]] 
    opt some rules 
    'then 
    opt [some rules | ahead 'then | skip] 
] 

注:

  • 私はできるだけ明示的な文法規則を作ってみました。
  • someを使用して、サブ式を繰り返し消費することに注意してください。
  • ahead 'thenガードルールでは、skipが親式の一部であるthenを消費しないようにしています(再帰的な呼び出しの場合)。
  • thenまたはelseに続くターミナル値を渡すのにskipを使用しますが、複数の値が存在する可能性がある場合は説明からわかりません。とにかく、必要に応じてより複雑なパターンをマッチさせるために拡張するのは簡単です。

あなたが入力をスキップするようなルールを使用したい場合は、このようにそれを呼び出すことができます。

skip-ifs: [to 'if rules] 

は、この情報がお役に立てば幸いです。

+0

あなたのソリューションはありがたいですが、ルールの最後の項目です: 'opt [some rules | | skip] 'は現在の直後に' if'があればスキップします。 '[if then then c then then] 'のようになります。私はただ1つの電流ifをスキップしたい、次のものが別々に処理される。これが可能だと思いますか? – user3033648

+0

'ahead 'を' ahead'に置き換えて ' 'then] 'を実行すると、このような異なるパターンも正しく解析されます。 – DocKimbel

+0

私は 'opt [いくつかのルール|先に['if' then] |スキップ] 'の最後の部分として、それはテストの半分に失敗します – user3033648

関連する問題