首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用Alex解析C风格的注释?

如何用Alex解析C风格的注释?
EN

Stack Overflow用户
提问于 2014-07-12 02:51:37
回答 1查看 1.4K关注 0票数 2

注意:我在用这个来自西蒙·马洛的亚历克斯模板

我想为C风格的评论创建lexer。我的当前方法为开始注释、结束、中间和单线创建单独的标记。

代码语言:javascript
复制
%wrapper "monad"

tokens :-
  <0> $white+ ;
  <0> "/*"               { mkL LCommentStart `andBegin` comment }
  <comment> .            { mkL LComment }
  <comment> "*/"         { mkL LCommentEnd `andBegin` 0 }
  <0> "//" .*$           { mkL LSingleLineComment }

data LexemeClass
  = LEOF
  | LCommentStart
  | LComment
  | LCommentEnd
  | LSingleLineComment
  • 如何减少中间令牌的数量?对于输入/*blabla*/,我将得到8个令牌,而不是一个!
  • 如何从单行注释令牌中删除//部件?
  • 在没有monad包装器的情况下,lex注释可以吗?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-07-12 08:18:22

看看这个:

http://lpaste.net/107377

使用以下内容进行测试:

代码语言:javascript
复制
echo "This /* is a */ test" | ./c_comment

其中应打印:

代码语言:javascript
复制
Right [W "This",CommentStart,CommentBody " is a ",CommentEnd,W "test"]

您需要使用的主要alex例程如下:

代码语言:javascript
复制
alexGetInput -- gets the current input state
alexSetInput -- sets the current input state
alexGetByte  -- returns the next byte and input state
andBegin     -- return a token and set the current start code

每个例程commentBegincommentEndcommentBody都有以下签名:

代码语言:javascript
复制
AlexInput -> Int -> Alex Lexeme

其中Lexeme代表您的令牌类型。AlexInput参数具有表单(用于monad包装):

(AlexPosn,Char,Bytes,String)

Int参数是存储在String字段中的匹配的长度。因此,大多数令牌处理程序的形式将是:

代码语言:javascript
复制
handler :: AlexInput -> Int -> Alex Lexeme
handler (pos,_,_,inp) len = ... do something with (take len inp) and pos ...

一般来说,处理程序似乎可以忽略Char[Bytes]字段。

处理程序commentBegincommentEnd可以忽略AlexInputInt参数,因为它们只匹配固定长度的字符串。

commentBody处理程序通过调用alexGetByte来积累注释体,直到找到"*/“。据我所知,C注释可能不是嵌套的,因此注释以"*/“的第一次出现结束。

注意,注释体的第一个字符位于match0变量中。事实上,我的代码中有一个错误,因为它不能正确匹配"/**/“。它应该看看match0来决定是从loop开始还是从loopStar开始。

您可以使用相同的技术来解析"//“样式注释-或任何需要非贪婪匹配的标记。

另一个关键点是,像$white+这样的模式使用开始代码进行限定:

代码语言:javascript
复制
<0>$white+

这样做是为了使它们在处理注释时不处于活动状态。

您可以使用另一个包装器,但是请注意,AlexInput类型的结构可能不同--例如,对于基本包装器,它只是一个三元组:(Char,[Byte],String)。只需查看生成的AlexInput文件中的.hs定义即可。

最后一个音符..。当然,使用++积累字符的效率相当低。您可能希望对累加器使用Text (或ByteString)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24709175

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档