J'ai essayé d'écrire un analyseur pour un interpréteur lambda-calculus qui utilise les grammaires expression closures de JavaScript 1.8, ce qui signifie function(x) x * x
même avec function(x) { return x * x; }
.Comment manipuler manuellement la précédence d'expressions spéciales dans Parsec?
Voici mon code d'analyseur.
module Parser where
import Text.Parsec
import Text.Parsec.String
import qualified Text.Parsec.Token as P
import qualified Text.ParserCombinators.Parsec.Token as T
import Text.Parsec.Language (emptyDef)
import Text.Parsec.Expr
import Control.Applicative ((<*>), (<$>), (*>), (<*), pure, (<$))
import Control.Monad
import Ast
jsparse :: String -> Either ParseError [Term]
jsparse = parse prog ""
-- The scanner.
lexer = P.makeTokenParser emptyDef {
T.commentStart = "/*",
T.commentEnd = "*/",
T.commentLine = "//",
T.nestedComments = True,
T.identStart = letter <|> char '_' <|> char '$',
T.identLetter = alphaNum,
T.reservedNames = ["function"],
T.reservedOpNames = ["="],
T.caseSensitive = True
}
parens = P.parens lexer
reserved = P.reserved lexer
identifier = P.identifier lexer
whiteSpace = P.whiteSpace lexer
semi = P.semi lexer
-- The parser
prog :: Parser [Term]
prog = expr `endBy` semi
term :: Parser Term
term = termE expr
termE :: Parser Term -> Parser Term
termE e = try (parens e) <|> try var <|> func
expr :: Parser Term
expr = do whiteSpace
e <- term
maybeAddSuffix e
where addSuffix e0 = do e1 <- term
maybeAddSuffix $ TermApp e0 e1
maybeAddSuffix e = addSuffix e
<|> return e
var :: Parser Term
var = do whiteSpace
v <- identifier
return $ TermVar v
func :: Parser Term
func = do whiteSpace
reserved "function"
v <- parens identifier
body <- term
return $ TermAbs v body
Cependant, il y a des problèmes que function(x) x(x)
doit être analysé à (function(x) (x(x)))
, mais mon analyseur obtient (function(x) x) (x)
.
Merci beaucoup et c'est résolu. J'ai appris ce framework de code à partir de https://github.com/JakeWheat/intro_to_parsing, mais je ne comprends pas le 'term' et' termE'. Pourquoi ai-je besoin de 'termE e' juste passer' expr' comme argument toujours? Comment puis-je le correspondre à BNF? – Ghjhdf
@fiigii Vous n'avez pas vraiment besoin de 'termE' dans un cas aussi simple, je suppose que le tutoriel l'utilise pour plus d'un but? Le reste est trop gros pour répondre dans un commentaire, peut-être que vous devriez poster une nouvelle question? –
Je l'ai eu. Je vous remercie. – Ghjhdf