解析时我需要添加什么才能将 monadUserState 与 alex 一起使用?
What do I need to add to use monadUserState with alex when parsing?
我正在尝试编写一个程序来理解允许嵌入注释的语言。如:
/* Here's a comment
/* This comment is further embedded */ second comment is closed
Must close first comment */
这应该被识别为评论(因此不会在第一个*/它看到时停止,除非它之前只看到 1 条评论打开)。
这在 C 中很容易解决,我可以简单地设置一个计数器,当它看到评论打开时递增,当它看到评论关闭时递减。如果计数器为 0,则我们处于 "code section".
但是,如果 Haskell 中没有状态,则更具挑战性。
我已经阅读了 monadUserState,据说它允许跟踪这种确切类型的解析的状态。但是,除了 tutorial page on alex.
之外,我找不到太多关于它的阅读 material
当我尝试编译时出现错误
templates\wrappers.hs:213:16: Not in scope: `alexEOF`
需要注意的是,我直接从 "basic" 包装器更改为 "monadUserState" 而没有更改我的代码(我不知道要添加什么才能使用它)。它说这必须在用户代码中初始化:
data AlexState = AlexState {
alex_pos :: !AlexPosn, -- position at current input location
alex_inp :: String, -- the current input
alex_chr :: !Char, -- the character before the input
alex_bytes :: [Byte], -- rest of the bytes for the current char
alex_scd :: !Int, -- the current startcode
alex_ust :: AlexUserState -- AlexUserState will be defined in the user program
}
我有点 lexxing noob,我完全不确定我应该在这里添加什么以使其至少可以编译...然后我可以担心事情的逻辑。
更新:此处提供工作示例:http://lpaste.net/119212
alex github 存储库中的文件 "tiger.x" (link) 包含一个示例,说明如何使用 monadUserState 包装器跟踪嵌入的评论。
很遗憾,该示例无法编译,但其中的想法应该可行。
基本上,这些行执行嵌入式评论处理:
<0> "/*" { enterNewComment `andBegin` state_comment }
<state_comment> "/*" { embedComment }
<state_comment> "*/" { unembedComment }
<state_comment> . ;
<state_comment> \n { skip }
至于 alexEOF
,想法是向您的令牌数据类型添加一个 EOF 令牌:
data Tokens = ... | EOF
并将alexEOF
定义为:
alexEOF = return EOF
有关此示例,请参阅 alex 存储库中的文件 tests/tokens_monadUserState_bytestring.x。
我正在尝试编写一个程序来理解允许嵌入注释的语言。如:
/* Here's a comment
/* This comment is further embedded */ second comment is closed
Must close first comment */
这应该被识别为评论(因此不会在第一个*/它看到时停止,除非它之前只看到 1 条评论打开)。
这在 C 中很容易解决,我可以简单地设置一个计数器,当它看到评论打开时递增,当它看到评论关闭时递减。如果计数器为 0,则我们处于 "code section".
但是,如果 Haskell 中没有状态,则更具挑战性。
我已经阅读了 monadUserState,据说它允许跟踪这种确切类型的解析的状态。但是,除了 tutorial page on alex.
之外,我找不到太多关于它的阅读 material当我尝试编译时出现错误
templates\wrappers.hs:213:16: Not in scope: `alexEOF`
需要注意的是,我直接从 "basic" 包装器更改为 "monadUserState" 而没有更改我的代码(我不知道要添加什么才能使用它)。它说这必须在用户代码中初始化:
data AlexState = AlexState {
alex_pos :: !AlexPosn, -- position at current input location
alex_inp :: String, -- the current input
alex_chr :: !Char, -- the character before the input
alex_bytes :: [Byte], -- rest of the bytes for the current char
alex_scd :: !Int, -- the current startcode
alex_ust :: AlexUserState -- AlexUserState will be defined in the user program
}
我有点 lexxing noob,我完全不确定我应该在这里添加什么以使其至少可以编译...然后我可以担心事情的逻辑。
更新:此处提供工作示例:http://lpaste.net/119212
alex github 存储库中的文件 "tiger.x" (link) 包含一个示例,说明如何使用 monadUserState 包装器跟踪嵌入的评论。
很遗憾,该示例无法编译,但其中的想法应该可行。
基本上,这些行执行嵌入式评论处理:
<0> "/*" { enterNewComment `andBegin` state_comment }
<state_comment> "/*" { embedComment }
<state_comment> "*/" { unembedComment }
<state_comment> . ;
<state_comment> \n { skip }
至于 alexEOF
,想法是向您的令牌数据类型添加一个 EOF 令牌:
data Tokens = ... | EOF
并将alexEOF
定义为:
alexEOF = return EOF
有关此示例,请参阅 alex 存储库中的文件 tests/tokens_monadUserState_bytestring.x。