【编译原理】原理笔记

随便记点防止期末烂掉

自顶向下

直接左递归的消除

实际就是左递归转右递归

法1:直接替换

\[A\rightarrow A\alpha|\beta \Rightarrow \begin{cases} A\rightarrow \beta A',\\ A'\rightarrow \alpha A'|\epsilon \end{cases} \]


法2:矩阵法

前置知识:

\[I = \begin{pmatrix} \epsilon & \empty\\ \empty & \epsilon \end{pmatrix}\\ A^* = I + AA^* \]

原理:

\[X\rightarrow XA|B\Rightarrow X=BA^* \]

例题

\[S\rightarrow AS|b, A\rightarrow SA|a\\ 解 S=AS+b,A=SA+a\\ (S,A)=(S,A) \begin{pmatrix} \empty & A\\ S & \empty \end{pmatrix} +(b, a)\\ (S,A)\rightarrow (b,a) \begin{pmatrix} \empty & A\\ S & \empty \end{pmatrix}^*\\ 令Z = \begin{pmatrix} \empty & A\\ S & \empty \end{pmatrix}^*, 则 Z=I+ \begin{pmatrix} \empty & A\\ S & \empty \end{pmatrix} Z\\ 则原文法改写为:(S,A)=(b,a)Z\\ Z=I+ \begin{pmatrix} \empty & A\\ S & \empty \end{pmatrix} Z \]

求FIRST集

就只看右边推出来的第一个字符就好了

\(A\to B\):FIRST 就是 \(B\) 的第一个字符(B可以是一坨)

求FOLLOW集

起始符先加入一个 # 到集合中

看右边的右边:\(B\to \alpha A\beta\)\(\beta\) 可以是一坨东西)
看产生式右边的 \(\beta\)

  1. \(\beta\) 是终结符,= 终结符
  2. \(\beta\) 是非终结符,= FIRST(\(\beta\))- ε
  3. \(\beta\) 是空,= FOLLOW(\(B\)

FOLLOW里面不可能有 \(\epsilon\)

\(\forall X\in V_N\),有 # $ \in FOLLOW(X)$,条件是: \(S\Rightarrow^* \alpha X\),其中 \(\alpha\in(V_N ∪ V_T)^*\)

SELECT集

对于 \(A\to \alpha\)

\(\alpha\) 能推出空:\(\{FIRST(\alpha)-\epsilon\} \,\,∪\,\,\{FOLLOW(A)\}\)
\(\alpha\) 不能推出空:\(FIRST(\alpha)\)

LL(1)文法

同一非终结集的文法的 \(SELECT\) 集无交集

自底向上

LR(0)分析表构造

1.扩展文法:加一条 \(E'\to E\),并且把所有并在一起的拆开来写成单产生式
2.写 \(I_0\):扩展后的文法,每一条右边加上 \(·\),比如 \(E'\to E\) 变为 \(E'\to ·E\)
3.对 \(I_0\) 中的每一条产生式分析,根据 · 后面接收的字符转移到下一个状态。新状态中 · 右移一位,右移后 · 的右边如果接的是非终结符,则要把该非终结符对应的所有产生式写在当前新状态里。例:\(E\to ·ET\) 接收 \(E\) 转移到 \(\{E\to E·T\)\(T\to ...\)\(T\to ...\}\)
4.注意新生成的状态中,如果产生式是已经存在于某个状态的,就直接转移过去(也有可能转移到自身)
5.一直重复对状态的转移,直至状态中所有的产生式的 · 都在最右边
6.状态转移图生成完之后就可以开始写分析表了,框架是:列为状态,有多少个状态就写多少列;行是所有产生式右侧出现过的符号,分为终结符ACTION和非终结符GOTO
7.接着开始根据状态图填表:按出边填

  1. 当前状态有出边:转移到ACTION要在状态前加一个s,转移到GOTO直接写下状态的数字
  2. 当前状态无出边(终结态):如果当前状态对应的是第 \(i\) 条产生式,直接把这一行的ACTION全部写上 \(r_i\)
  3. 确定 \(acc\) 态:\(E'\to E\,·\) 所在的状态,# 那列

例题

参考

LR(0) 分析步骤

分析串s

1.表头:状态,符号,输入串
2.第一行:0,#,s#
3.查ACTION表,看上一行状态的最后一位接收串的第一个字符后到达什么状态:

  1. \(s_i\) :状态后加上 \(i\)当前输入串的第一个字符挪到符号后;
  2. \(r_i\) :找到第 \(i\) 个产生式,把符号后缀对应的产生式右侧(假设长度为 \(n\))替换为左侧非终结符此时为了保证状态数和符号数一样,对应状态也要舍去后面的\(n\) 个状态。舍去后状态数比符号数少一个,继续查GOTO表当前状态的最后一位接收符号的最后一位得到的数字填上去,保证数量一样。输入串不变。
  3. \(acc\):接收成功,分析结束
    4.注意状态数和符号数始终相等

例题


参考

第五章

综合属性继承属性

参考

addtype
参考

$$:产生式左侧的字符的属性

posted @ 2024-04-23 15:41  Sakana~  阅读(28)  评论(0编辑  收藏  举报