我正在从头开始创建一个简单的命令式语言,我已经有了一个工作语法树,没有太多复杂性,它只是使用自下而上的解析方式使用简单的树数据结构来创建它。现在的想法是实现一个完整的 LeBlanc-Cook 风格的符号表。它的结构并不复杂,问题是我不知道如何在创建树的同时让快乐填充它。
一次性完成所有操作背后的想法是,通过这种方式,AST 可以只填充最少必要的内容,而忽略变量或类型声明之类的内容,这些内容只有符号表中的效果。遍历 AST 来填表是我最后的选择。
我的基本概念是它是某种全局状态,仅在某些选择时间进行修改,例如打开新块或声明变量时,但我不知道如何使用快乐给我的环境使用我将创建的任何一元结构。
我知道这个问题可以简化为“快乐是如何工作的?”,但无论如何。任何评论表示赞赏。
这是一个例子来更好地说明我的问题。
% monad {MyState}
...
START: INSTRUCTIONS { (AST_Root $1, Final_Symtable_State) } -- Ideally
INSTRUCTIONS: INSTRUCTIONS INSTRUCTION { $2:$1 } -- A list of all instructions
| INSTRUCTION { [$1] }
INSTRUCTION : VARDEF {%???}
| TYPEDEF
| VARMOD
| ...
...
VARDEF: let identifier : Int {%???} -- This should modify the symtable state and not the tree
| let identifier : Int = number {%???} -- This should modify the symtable and provide a new branch for the tree
似乎单个状态可能无法解决,并且存在单子和非单子动作的组合,解决此问题的最佳结构是什么。