3

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).

Répondre

3

Dans la définition de func, body <- term signifie que le corps ne peut se composer que d'un terme simple. Pour autoriser toutes les expressions dans un corps de fonction, remplacez-le par body <- expr.

+0

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

+1

@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? –

+0

Je l'ai eu. Je vous remercie. – Ghjhdf