编译原理与编译构造 课堂笔记9

来源:互联网 发布:易语言2017盗号源码 编辑:程序博客网 时间:2024/06/09 17:06

DFA 转换表

例:

Ii a b 0 1 2 1 1 3 2 3 3 1

则由表的前两行得 I0aI1,I0bI2

大概代码如下

state = 0;while(1) {    ch = getchar();    s = lookup(state, ch);    if(s == ' ' && s is non-terminal state) {        error;    } else if(s == ' ' && s is terminal-state) {        ungetchar();        return;    } else {        state = s;    }}

Language By experience RE

  1. 逐步求精法
  2. FA-based

例:一个2进制数能被3整除,我们做出在某个数后面添加一个0/1后模3余的结果电路转换图

Markdown

语法分析

自上而下

递归下降分析法

一个非终结符对应一个子程序

若有以下文法:

SaA|bB

AcD|d

BeB|f

Dg

则有对应程序:

int S() {    ch = getchar();    if(ch == 'a') {        return A();    } else if(ch == 'b') {        return B();    } else {        return 0;    }}int A() {    ch = getchar();    if(ch == 'c') {        return D();    } else if(ch == 'd') {        return 1; // 表示结束    } else {        return 0; // 表示出错    }}// 其余同理

换一种文法:

SaA|aB

AAd|d

BBe|e

int S() {    ch = getchar();    if(ch == 'a') {        if(A()) {            return 1;        } else {            return B();        }    }}int A() {    A();    if(ch == 'd') {        return 1;    } else {        return 0;    }}

在这种情况下会出现回溯和栈溢出

不能出现公共左子表达式和左递归,会出现回溯。

因此想用这种方法的话,对文法的要求比较高。

预测分析法

预处理:

提取最大公共左子表达式

消除左递归

把左递归变成右递归的形式

左递归:

  • 直接左递归:AAα|β
  • 间接左递归: ABα|β,BAβ|θ
消除直接左递归

AAα|ββ,βα,βα2,,βαn,βαn(n0)

αn=A ,则有AβA,Aϵ|αA

消除间接左递归

SQc|cQRb|bRSa|a

此时有间接左递归

我们强行规定优先级:S>Q>R

SQc|cQRb|bRSa|a(Qc|c)a|aQca|ca|a(Rb|b)ca|ca|aRbca|bca|ca|a

此时由消除直接左递归的方法得,R(bac|ca|a)RRbcaR|ϵ

先消除直接左递归,再消除间接左递归

SQc|cQQd|Rb|bRSa|a

Q(Rb|b)QQdQ|ϵ

SQRSQc|cQ(Rb|b)QQdQ|ϵR(Qc|c)a|aQca|ca|a(Rb|b)Qca|ca|aRbQca|bQca|ca|a

此时再用消除直接左递归的方法再消除一下就好了

原创粉丝点击