2

プログラミング言語用のパーサーを作成する必要があります。これまでのところ、細かい部分を除いて、95%完了しています。

この言語で書かれたプログラムの構造は次のとおりです。

outputs
inputs
expressions

要件は、出力を入力と混合できないことです。例えば:

x := output of int;
y := output of in;
.....
z := input of int;
t := input of in;
.....
expressions

単一の出力を問題なく解析できますが、(many1出力)を使用して複数の出力を許可しようとすると、入力を出力として解析しようとするため、機能しません。

私のメインパーサーは次のようになります。

prog =
    do outs <- many1 output
       ins <- many1 input
       exs <- expressions
       eof
       return (Prog outs ins exs) 

簡単そうに見えますが、いろいろ試してみましたが、うまくいきません。助けてください。

4

2 に答える 2

3

出力のルールが次のようになっている場合:

output = do name <- ident
            string ":= output of"
            type <- ident
            char ';'
            return $ Out name type

入力ルールは「inputof」を除いて同じように見えます。問題は、両方のルールがanidentで始まり、parsecが自動的にバックトラックしないため、output最初に適用を試み、を消費し、ident可能な場合は失敗することです。 tは「の出力」と一致します。

これを修正するには、ラップoutputしてinputインするだけです。try

outs <- many1 (try output)
ins <- many1 (try input)
于 2010-10-30T12:59:15.200 に答える
0

sepp2kの答えは機能しますが、私は個人的に、出力パーサーと入力パーサー内にバックトラックをカプセル化したいと思います。

これによりパーサーにコードが追加されますが、パーサーはより堅牢になります。

output = do name <- try prefix
            type <- ident
            char ';'
            return $ Out name type
  where
    prefix = do name <- ident
                string ":= output of"
                return name

Parsecでは、Char Parsersを除いて試行を避け、文法を改善するために左因数分解を使用するのが一般的に最善です(試行すると、パーサーが非常に脆弱になる可能性があります)。残念ながら、あなたが取り組んでいる文法は左再帰に特に適しているわけではなく、この場合、おそらく気にする価値はありません。

于 2010-10-30T16:50:41.297 に答える