抽象语法分析 问题记录

到目前为止 完成了词法分析 语法分析 抽象语法生成的全部内容 。
记录以下出现的问题

问题一
书上提到貌似多余的一条规则,书上只是指出了和哪一条规则是相关的
但是并没有进行说明具体是哪一条规则

但是实践中 问题自然的出现了
有以下的文法规则

0 exp -> id[ exp ] of exp
1 exp -> lvalue

2 lvalue -> lvalue [ exp ]
3 lvalue -> id

试想 当读取到一个id 的时候 会有 规约(为lvalue)/移进(exp规则) 冲突
规约为 lvalue 后 后一个字符仍可能是 [
移进为 0 时 后一个字符可以是 [

这里是因为这个id 过早的判断了究竟是lvalue 还是一个 exp 的部分

于是就只要推迟这个判断的时间就行了 通过添加下面的文法规则即可

4 lavlue -> id [ exp ]

添加了这个文法规则以后 虽然 规约 移进冲突仍然会发生,但是yacc 默认选择的是移进
相比之前 选择移进丢失了规约成 lvalue 的可能,这样处理就将判断时刻推迟了许多

这样就就是看似多余的一条文法规则了

问题二
文件的组织,
这里我简单复述一下

词法分析器由 flex 生成
语法分析器由 yacc 生成
具体的生成顺序可见 makefile

语法分析器中声明乐 yylex 作为提取 token 的函数
语义绑定通过 %union 指定一个联合体
yacc 生成的 y.tab.c 中实际上生成了一个结构 这个结构也就是 yylval 的类型
作为绑定 token 的东西
实际上 ID String 的语义值绑定在 词法分析阶段就完成乐

具体的组织见代码

问题三
递归定义和嵌套 (包括函数和类型两种)

这里做了一个假设化的假定 假定只有 相邻的函数或定类型定义会涉及嵌套

问题四

seqexp 的问题
在 let decs in expseq end 文法中的时候

注意首先 这里是 expseq (在说明中明确了这里没有分号)

但是自然意义上的 expseq 是exp 的组合 也就是说一定会有这样一条语法

exp - > ( expseq )

但是给出的 A_LetExp 中接受的是 exp 类型 不是 Explist

这里采用的方法也是 一样使用提前嵌套的方式

问题五
重名文题
给出的辅助头文件有几个名字迷惑性太大
比如 fundc系列的

还有NameTy 系列的
建议或一个图梳理一下具体的关系

原文地址:https://www.cnblogs.com/sfzyk/p/9637440.html