我目前正在编写玩具语言编译器的解析器
使用Happy&亚历克斯。由于需要某种形式的可选布局,我必须改变
Alex匹配block
非终端之前的状态。不幸
似乎Happy之前需要前瞻标记
我有机会改变亚历克斯的状态。
这是一个展示问题的小片段:
funcDef : header localDefs block
^ I have to change alex's state
before the underlying lexer
starts reading the block tokens.
这个问题有一个共同的方法吗?
答案 0 :(得分:0)
我假设您正在使用线程词法分析器(因此Happy和Alex在同一个monad中运行)。我遇到类似问题时使用的技巧是制作一个空的生产规则,并将其纳入规则。
changeAlexState :: { () }
: {- empty -} {%% \tok -> changeAlexState *> pushTok tok }
funcDef : header localDefs changeAlexState block
然后,你需要向你的monad添加一些状态以支持pushTok :: Token -> P ()
(其中P
是你的lexing /解析monad)并确保你在lexing时总是弹出那个标记。 %%
的作用是documented here。
n : t_1 ... t_n {%% <expr> }
...
<expr>
的类型相同[仍为Token -> P a
],但在这种情况下,预测标记实际上被丢弃,并从输入中读取新标记。当您想要更改下一个标记并继续解析时,这非常有用。
我提到我不久前做了类似的事情。 Here is my "empty" rule,here is an example use of it,here is where my pushing function is defined和here is where I "pop" tokens。让我知道它是怎么回事!