haskell - 如何在 Parsec 中手动操作特殊表达式的优先级?

标签 haskell compiler-construction interpreter parsec lambda-calculus

我尝试为使用 expression closures 的 lambda 演算解释器编写解析器JavaScript 1.8 的语法,这意味着 function(x) x * xfunction(x) { return x * x; 相同}

这是我的解析器代码。

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 

但是有个麻烦,function(x) x(x)应该解析成(function(x) (x(x))),但是我的解析器得到 (function(x) x) (x)

最佳答案

func的定义中, body <- term意味着主体只能由一个简单的术语组成。要允许函数体中的所有表达式,请将其更改为 body <- expr .

关于haskell - 如何在 Parsec 中手动操作特殊表达式的优先级?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28825807/

相关文章:

haskell - 在 Haskell 中,用户如何将项目添加到列表中

c++ - 为什么链接了很多目标文件而不是一个大目标文件?

Objective-C 编译器和编辑器

python - Mac : How can I use Python 3. 7 在 Visual Studio Code 的命令行中?

python - 如何在 sublime text 2 中配置 python 解释器以使其充当 IDLE python shell

haskell - 库用户还需要编译库所需的静态 .lib 吗?

Haskell 无限循环,只需简单的 re-let 操作

haskell - llvm-general 的 cabal 安装失败

compiler-errors - 到底应该使用什么命令行来从 <Target>RegisterInfo.td 文件中生成所有记录?

java - 除了缓存指令之外,解释器生成的 native 代码和 JIT 之间有什么区别吗?