2
私はParsecで簡単な言語を解析しようとしています。 "x = y"というアサインメントや "prefix test"のような接頭辞があります。ただし、割り当ての解析ルールは貪欲で、「=」がない場合は失敗しません。たとえば、Parsecでプレフィックスを使用しない解析操作
parse tp "" "prefix foo"
は、解析エラーとなります。対応するコード:
module Test where
import Text.ParserCombinators.Parsec
import Text.ParserCombinators.Parsec.Language
import Text.ParserCombinators.Parsec.Expr
import qualified Text.ParserCombinators.Parsec.Token as P
lexer = haskell
reserved = P.reserved lexer
reservedOp = P.reservedOp lexer
data Term = Term String
deriving (Show)
term :: Parser Term
term = do { x <- many alphaNum
; reservedOp "="
; y <- many alphaNum
; return (Term (x++y))
}
<|> do { reserved "prefix"
; x <- many alphaNum
; return (Term x)
}
tp = do { e<-term; return e }
何が欠けていますか?私のアプローチは可能ですか、私はParsecを誤解しましたか?
「予約済み」接頭辞「?」の後に 'spaces'を挿入する方法はありますか? – jeiea
私たちは決してこれまでに来たことはない、パーサーは最初のことしか見ない。ルールの順序を変更すると、ステートメントは正しく解析されます。これは、この単純なケースでのみ機能しますが、最初のルールのように多くのルールがあれば、このトリックはもう機能しません。 – hexhex
多くのalphaNumは "接頭辞"を消費しますが、失敗すると動作しません - 入力を消費した後にパーサが失敗すると、別の代替( '<|>'や 'choice'などで与えられます)を試みません。最初のパーサで 'try'が必要です。 (私はあなたが誤ってparsecしていると思う - あなたは自動バックトラックを期待しているが、parsecはこれをしないだけで、他のパーサライブラリがあると思う) – user2407038