用c语言编写lr(1)文法,C语言编写源程序建立LR(1)分析器.pdf

目 录

前 言2

用C语言编写源程序建立LR(1)分析器3

一,设计目的,要求,算法与设计思想3

1.设计内容3

2.设计要求3

3.设计的基本原理3

1.CLOSURE(I)的构造3

2.GO(I,X)的构造3

3.FIRST集合的构造4

4.LR(1)分析表的构造4

二,LR (1)分析器4

1.LR(1)分析器的实现图:4

2.LR分析器与逻辑结构及工作过程5

三,总体方案设计5

1. 各模块设计6

四,程序测试8

1.教科书的第142页文法的LR1分析器的构造和语法分析8

2.表达式文法的LR1分析器的构造和语法分析器9

五,源程序10

六,总结19

七,参考文献19

编译原理学年论文

前 言

《编译原理》是计算机专业的一门重要的专业课程,其中包含大量软件设计

细想。通过课程设计,实现一些重要的算法,或设计一个完整的编译程序模型,

能够进一步加深理解和掌握所学知识,对提高自己的软件设计水平具有十分重要

的意义。

我选的是老师给的题,并予以扩充。即对任意给定的问法G构造LR(1)项目

集规范族,其中要实现CLOSURE(1),GO(I,X),FIRST集合符。在此基础上,构

造了LR(1)分析表。然后对输入的句子进行语法分析,给出接受或出错报告。程

序采用文件输入输出方式。其中包括两个输入文件:文法grammar.txt,以及输

入串 input.txt;两个输出文件:项目集 items.txt 和文法的LR(1)分析表

action_table.txt。由于语法分析的结果只给出接受或错误报告,比较简单。所

以直接在屏幕上输出,也便于用户查看。

在具体编写程序中,对文法操作的各个功能模块独立成为一个子程序,而对

具体输入穿得分析则放在main()函数中进行。各个变量奇函数的意义和用法我

将在论述程序设计的通体方案中向西给出。

程序的通体算法细想来自《编译原理》课程。具体实现有我独立完成。程序

用C/C++语言编写。在Microsoft Visual C++2005环境下调使通过。

2

编译原理学年论文

用C语言编写源程序建立LR(1)分析器

一,设计目的,要求,算法与设计思想

1.设计内容

对任意给定的上下文无关文法G,构造其LR(1)项目集族,并且在此基础上

进一步构造其LR(1)分析表。然后分析输入的句子。

2.设计要求

对输入 的文法 G (要求是上下文无关文法 ),在程序 终实现

CLOSURE(1),GO(I,X),FRIST等的构造,并利用这些功能函数构造出LR(1)项目

集族。并且输出结果。在此基础上构造G 的LR(1)分析表(这个表也输出给用户),

并对输入的句子进行语法分析表,给出分析结果。

3.设计的基本原理

1.CLOSURE(I)的构造

CLOSURE(I)表示和I中项目可以识别同样活前缀的所有项目的集合。它可以

有以下方法得到:

(1)I中的所有项目都属于CLOSURE(I);

→a.Bβ,a] →

(2)若项目[A 属于CLOSURE(I),B ξ是一个产生式,那么,对于

β β→

FIRST< a>中的每一个中介符b,如果[ .ξ,b]原来不在CLOSURE(I)中,则把它

加进去;

(3)重复执行步骤 (2),直到CLOSURE(I)不再增大为止。

2.GO(I,X)的构造

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的 LR(0) 分析程序的 C 语言代码示例: ```c #include <stdio.h> #include <string.h> #define MAX_STATE_NUM 100 #define MAX_SYMBOL_NUM 100 typedef struct { int next_state[MAX_SYMBOL_NUM]; int reduce_prod; // 产生式编号,-1 表示不能规约 } state_t; state_t states[MAX_STATE_NUM]; int state_num = 0; int symbol_num; char symbols[MAX_SYMBOL_NUM]; // 终结符和非终结符的集合 int start_symbol; // 开始符号编号 int prod_num; char prods[MAX_SYMBOL_NUM][100]; // 产生式 int parse_table[MAX_STATE_NUM][MAX_SYMBOL_NUM]; // 添加一个新状态 int add_state() { int i; state_t *new_state = &states[state_num++]; for (i = 0; i < symbol_num; i++) { new_state->next_state[i] = -1; } new_state->reduce_prod = -1; return state_num - 1; } // 判断一个状态是否已经存在 int find_state(int next_state[MAX_SYMBOL_NUM], int reduce_prod) { int i, j; for (i = 0; i < state_num; i++) { state_t *s = &states[i]; if (s->reduce_prod != reduce_prod) { continue; } for (j = 0; j < symbol_num; j++) { if (s->next_state[j] != next_state[j]) { break; } } if (j == symbol_num) { return i; } } return -1; } // 计算闭包 void closure(int state[MAX_SYMBOL_NUM], int size, int result[MAX_SYMBOL_NUM], int *result_size) { int i, j; for (i = 0; i < size; i++) { result[i] = state[i]; } *result_size = size; for (i = 0; i < prod_num; i++) { char *prod = prods[i]; for (j = 0; j < *result_size; j++) { if (symbols[result[j]] == prod[0]) { result[*result_size] = i; (*result_size)++; } } } } // 计算移进后的状态 void shift(int state[MAX_SYMBOL_NUM], int size, int symbol, int result[MAX_SYMBOL_NUM], int *result_size) { int i, j; for (i = 0; i < size; i++) { result[i] = states[state[i]].next_state[symbol]; } *result_size = size; for (i = 0; i < size; i++) { for (j = i + 1; j < size; j++) { if (result[i] == result[j]) { result[j] = -1; } } } for (i = 0; i < size; i++) { if (result[i] == -1) { for (j = i; j < size - 1; j++) { result[j] = result[j + 1]; } (*result_size)--; } } } // 计算一个状态的 LR(0) 闭包 void lr0_closure(int state[MAX_SYMBOL_NUM], int size, int result[MAX_SYMBOL_NUM], int *result_size) { int i, j; closure(state, size, result, result_size); for (i = 0; i < *result_size; i++) { int prod = result[i]; char *p = prods[prod]; for (j = 1; p[j] != '\0'; j++) { if (p[j] == symbols[start_symbol]) { break; } if (p[j] == symbols[p[0]]) { int k; for (k = 0; k < *result_size; k++) { if (result[k] == prod) { break; } } shift(result, *result_size, p[0], result, result_size); if (k < *result_size) { k = find_state(result, -1); if (k == -1) { k = add_state(); memcpy(states[k].next_state, result, symbol_num * sizeof(int)); } states[k].reduce_prod = prod; } break; } } } } // 构造 LR(0) 自动机 void build_lr0_parser() { int i, j; int state[MAX_SYMBOL_NUM]; int state_size; state[0] = 0; state_size = 1; lr0_closure(state, state_size, state, &state_size); while (1) { for (i = 0; i < symbol_num; i++) { if (states[0].next_state[i] != -1 && i == symbols[start_symbol]) { parse_table[0][i] = 1; } else if (states[0].next_state[i] != -1) { shift(state, state_size, i, state, &state_size); int k = find_state(state, -1); if (k == -1) { k = add_state(); memcpy(states[k].next_state, state, symbol_num * sizeof(int)); } parse_table[0][i] = k; } } if (state_size == 0) { break; } lr0_closure(state, state_size, state, &state_size); } } // 构造 LR(1) 自动机 void build_lr1_parser() { // TODO: 实现 LR(1) 分析器的构造 } int main() { // TODO: 读入文法,初始化 symbols、start_symbol、prod_num、prods 等变量 build_lr0_parser(); build_lr1_parser(); // TODO: 使用分析器进行语法分析 return 0; } ``` 关于如何构造 LR(1) 分析器,可以参考类似《编译原理》这样的教材,这里就不再赘述。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值