1

我目前正在使用 Happy & Alex 为玩具语言的编译器编写解析器。由于需要某种形式的可选布局,我必须在匹配block非终端之前更改 Alex 的状态。不幸的是,在我有机会更改 Alex 的状态之前,Happy 所需的前瞻令牌似乎已被读取。

这是一个演示问题的小片段:

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

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

4

1 回答 1

1

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

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

funcDef : header localDefs changeAlexState block

然后,您需要向您的 monad 添加一些状态以支持pushTok :: Token -> P ()P您的 lexing/parsing monad 在哪里)并确保在您进行词法分析时始终弹出该标记。%%这里记录了什么。

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

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

我提到我不久前做了类似的事情。这是我的“空”规则这是一个使用它的示例这是我的推送功能被定义的地方,这是我“弹出”令牌的地方。让我知道事情的后续!

于 2017-03-25T16:43:27.533 回答