小编ser*_*eyz的帖子

在Haskell中实现语言解释器

我想在Haskell中实现一个命令式语言解释器(用于教育目的).但是我很难为我的翻译创建正确的架构:我应该如何存储变量?如何实现嵌套函数调用?我该如何实现变量范围?如何在我的语言中添加调试功能?我应该使用monads/monad变压器/其他技术吗?等等

有没有人知道关于这个主题的好文章/论文/教程/来源?

interpreter haskell

19
推荐指数
2
解决办法
1万
查看次数

haskell中具有循环依赖性的数据结构

我正在尝试使用parsec库在haskell中实现简单的解析器(用于学习目的).所以我写了一堆数据结构和相关的函数,如下所示:

data SourceElement 
    = StatementSourceElement Statement
    | FunctionSourceElement FunctionName FunctionBody

data Statement 
    = IfStatement Expr Statement Statement
    | WhileStatement Expr Statement

data FunctionBody = FunctionBody [SourceElement]

parseSourceElement :: Parser SourceElement
parseSourceElement = ...

parseFunctionBody :: Parser FunctionBody
parseFunctionBody = ...
Run Code Online (Sandbox Code Playgroud)

它工作正常.现在我想将这些东西分成两个模块来分离FunctionBodyStatement数据结构(因为可读性问题).但我不能!原因是SourceElement和之间的循环依赖FunctionBody.

那么,有什么方法可以解决这个问题吗?

haskell cyclic-reference

12
推荐指数
2
解决办法
1067
查看次数

Parsec和自定义解析错误类型

是否有可能以某种方式获得某些自定义类型的解析错误?例如,从错误中获取有关解析上下文的更多信息会很酷.以文本消息的形式出现错误信息似乎不太方便.

haskell parsec

10
推荐指数
1
解决办法
405
查看次数

构成延续和状态monad变换器的正确方法

我有用haskell写的原始翻译.这个解释器可以正确处理return语句(参见我之前的问题).

现在我想将全局状态添加到我的解释器中.可以从全局代码或函数代码更改此状态(函数的代码runCont用于提供return逻辑).

代码如下:

import Control.Monad.Cont
import Control.Monad.State

type MyState = String
data Statement = Return Int | GetState | SetState MyState | FuncCall [Statement] deriving (Show)
data Value = Undefined | Value Int | StateValue MyState deriving (Show)

type Eval a = StateT MyState (Cont (Value, MyState)) a

runEval ::(Eval Value) -> MyState -> (Value, MyState)
runEval eval state = runCont (runStateT eval state) id

evalProg :: [Statement] -> Value
evalProg stmts …
Run Code Online (Sandbox Code Playgroud)

continuations state haskell monad-transformers

8
推荐指数
1
解决办法
605
查看次数

用continuation重写代码

我有一些代码来评估原始程序.程序是一个语句列表(表达式,块,返回语句).评估结果是最后评估的表达式.评估员也应妥善处理return陈述(即首次出现后停止评估return).

为了实现这个逻辑,我传递了特殊的回调函数(NextStep),它在当前语句之后进行下一个评估步骤.处理return语句时我不调用下一步:

data Statement = 
      Expr Int
    | Block [Statement]
    | Return Int
    deriving (Show, Eq)

data Value = 
      Undefined
    | Value Int
    deriving (Show, Eq)

type NextStep = Value -> Value

evalStmt :: Statement -> NextStep -> Value
evalStmt (Expr val) next = 
    let res = Value val
    in next res
evalStmt (Block stmts) next = evalBlock stmts next
evalStmt (Return val) next = Value val

evalBlock :: [Statement] -> NextStep -> Value …
Run Code Online (Sandbox Code Playgroud)

continuations haskell continuation-passing

5
推荐指数
1
解决办法
159
查看次数

是否可以编写c ++模板/宏来检查两个函数是否具有相同的签名

是否可以编写c ++模板/宏来检查两个函数是否具有相同的签名(返回类型和参数列表)?

这是一个我想如何使用它的简单示例:

int foo(const std::string& s) {...}
int bar(const std::string& s) {...}

if (SAME_SIGNATURES(foo, bar))
{
    // do something useful... make Qt signal-slot connection for example...
}
else
{
    // signatures mismatch.. report a problem or something...
}
Run Code Online (Sandbox Code Playgroud)

那么它有可能或者只是一个白日梦吗?

PS其实我对c ++ 2003标准感兴趣.

c++ templates sfinae c-preprocessor

4
推荐指数
1
解决办法
894
查看次数

如何获取 erlang 故障转储文件?

我的程序在执行期间崩溃并在控制台上写入Segmentation fault (core dumped)。但当前工作目录中没有任何生成的文件。问题是在哪里可以找到生成的故障转储文件?我正在使用 Ubuntu 13.04 / Erlang R15B01

erlang crash-dumps

4
推荐指数
1
解决办法
5060
查看次数

c预处理器中的宏评估

我想做这样的事情:

#define NUM_ARGS() 2
#define MYMACRO0(...) "no args"
#define MYMACRO1(...) "one arg"
#define MYMACRO2(...) "two args"
#define MYMACRO(num,...) MYMACRO##num(__VA_ARGS__)
#define GENERATE(...) MYMACRO(NUM_ARGS(),__VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)

我期望它评估为"两个参数".但相反,我有

MYMACRONUM_ARGS()(1,1)
Run Code Online (Sandbox Code Playgroud)

有没有办法做我想要的(使用visual c ++)?

PS最终我想实现转储所有变量的记录器.下一个代码

int myInt = 7;
string myStr("Hello Galaxy!");
DUMP_VARS(myInt, myStr);
Run Code Online (Sandbox Code Playgroud)

将产生日志记录 "myInt = 7; myStr = Hello Galaxy!"

c c-preprocessor

3
推荐指数
1
解决办法
2366
查看次数

添加其他信息到haskell类型

我的程序中有令牌数据类型.看起来像这样:

data Token
    = StringToken Strin
    | NumberToken Integer
    | IfToken
    | ElseToken
    ... -- lots of tokens here
Run Code Online (Sandbox Code Playgroud)

我在我的解析器中使用这种数据类型,它运行正常.但现在我想向令牌添加一些额外的信息(源位置信息).所以我可以更改我的数据类型声明并使用记录:

data Token
    = StringToken {value :: String, srcLoc :: SourceLocation}
    | NumberToken {value :: String, srcLoc :: SourceLocation}
    | IfToken {srcLoc :: SourceLocation}
    | ElseToken {srcLoc :: SourceLocation}
    ... -- lots of tokens here
Run Code Online (Sandbox Code Playgroud)

但这个解决方案对我来说似乎并不实用和美观.那么这个问题有更好的解决方案吗?谢谢.

haskell

3
推荐指数
1
解决办法
149
查看次数

在解释器中实现命令式返回语句

我正在尝试在haskell中实现简单的命令式语言.

一般来说,我的程序是一个语句列表(如算术表达式,if/then,块语句).我的评估者有简单的状态:词汇范围的堆栈.词法范围只是变量名称到值的映射.每当控制流进入功能或块时弹出词法范围,当控制流离开功能或阻塞时弹出.

但是我在尝试实现return语句评估时遇到了问题.我要做的是在主要评估函数(这里的源代码)中为return语句创建一个特例:

evalStatements :: [Statement] -> Eval MaybeValue

-- nothing to evaluate
evalStatements [] = return Nothing

-- current statement is 'return expr', 
-- evaluate expr and skip the rest of statements
evalStatements (ret@(ReturnStatement _expr):_stmts) =
    leaveLexEnv -- leave current lexical scope
    evalStatement ret >>= return

-- this is last statement in function, eval it and leave lexical scope
evalStatements [stmt] = do
    res <- evalStatement stmt
    leaveLexEnv -- leave current lexical scope
    return res …
Run Code Online (Sandbox Code Playgroud)

continuations haskell interpretation

3
推荐指数
1
解决办法
338
查看次数

制作Monad类的延续monad包装器实例

我的类型Foo是简单的包装Cont a a.我想使Foo类型成为类的实例Monad.我试试这个:

import Control.Monad.Cont

newtype Foo a = Foo {unFoo :: Cont a a}

instance Monad Foo where
    return = Foo . return
    Foo inner >>= func = Foo (inner >>= newFunc)
        where newFunc x = (unFoo $ func x)
Run Code Online (Sandbox Code Playgroud)

但我得到了这个错误:

Couldn't match type `a' with `b'
  `a' is a rigid type variable bound by
      the type signature for >>= :: Foo a -> (a -> Foo b) -> Foo b …
Run Code Online (Sandbox Code Playgroud)

monads continuations haskell class instance

0
推荐指数
1
解决办法
99
查看次数