【问题标题】:Happy & Alex - Preventing the lookahead from affecting parser-lexer communicationHappy & Alex - 防止前瞻影响解析器-词法分析器通信
【发布时间】:2017-03-25 09:57:05
【问题描述】:

我目前正在为玩具语言的编译器编写解析器 使用快乐和亚历克斯。由于需要某种形式的可选布局,我必须更改 Alex 在匹配 block 非终端之前的状态。很遗憾 好像之前读过Happy需要的lookahead token 我有机会改变亚历克斯的状态。

这是一个演示问题的小 sn-p:

funcDef : header localDefs block
                          ^ I have to change alex's state 
                            before the underlying lexer
                            starts reading the block tokens.

有解决这个问题的通用方法吗?

【问题讨论】:

  • 你怎么知道一个块从哪里开始?我认为localDefs 不是自动终止的,所以必须有一些词法特征可以用来知道块从哪里开始。你能解释一下吗?
  • @rici 该块要么被 begin/end 关键字包围,要么基于缩进。它基本上被定义为 begin stmts+ end 或 stmts autoend。当词法分析器检测到标识更改时,需要通知词法分析器缺少开始以生成自动结束。整个方法感觉很老套,必须有更好的方法。
  • 两周前我刚刚解决了这个exact问题。没想到其他人会碰到它。
  • @Alec 急切地等待细节!
  • 我会等着看@alec 写了什么,但我的方法是让解析器可以看到换行符,在这种情况下,可以在 before之前完成词法分析器的更改> 触发标记,或者在词法分析器中处理它。两者都有点hacky,但语法也是如此:)对比python对冒号的使用。

标签: parsing haskell compiler-construction happy alex


【解决方案1】:

我假设您使用的是线程词法分析器(因此 Happy 和 Alex 在同一个 monad 中运行)。我在遇到类似问题时使用的技巧是制定一个空的生产规则,然后将其放入规则中。

changeAlexState :: { () }
  : {- empty -} {%% \tok -> changeAlexState *> pushTok tok }

funcDef : header localDefs changeAlexState block

然后,您需要向您的 monad 添加一些状态以支持 pushTok :: Token -> P ()(其中 P 是您的 lexing/parsing monad)并确保在您进行词法分析时始终弹出该标记。 %% 所做的是 documented here

n : t_1 ... t_n {%% <expr> }

...<expr> 的类型是相同的[仍然是Token -> P a],但在这种情况下,前瞻标记实际上被丢弃了,并从输入中读取了一个新标记。当您想要更改下一个标记并继续解析时,这可能很有用。

我提到不久前我做过类似的事情。 Here is my "empty" rulehere is an example use of ithere is where my pushing function is definedhere is where I "pop" tokens。告诉我进展如何!

【讨论】:

    猜你喜欢
    • 2013-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多