c语言实现LL(1)分析器

时间: 2023-08-16 11:10:12 浏览: 48
下面是一个简单的C语言实现LL(1)分析器的代码示例,用于对输入的符号串进行语法分析。 ```c #include <stdio.h> #include <string.h> #define MAX_PROD 20 #define MAX_NT 10 #define MAX_T 10 char prod[MAX_PROD][MAX_NT+MAX_T+1]; char nt[MAX_NT]; char t[MAX_T]; char first[MAX_NT][MAX_T]; char follow[MAX_NT][MAX_T]; char select[MAX_PROD][MAX_T]; char table[MAX_NT][MAX_T+1][MAX_PROD+1]; int nnt, ntlen, ntstart, nprod, nterm; int is_nt(char c) { int i; for (i = 0; i < nnt; i++) if (nt[i] == c) return 1; return 0; } int is_t(char c) { int i; for (i = 0; i < nterm; i++) if (t[i] == c) return 1; return 0; } int find_nt(char c) { int i; for (i = 0; i < nnt; i++) if (nt[i] == c) return i; return -1; } int find_t(char c) { int i; for (i = 0; i < nterm; i++) if (t[i] == c) return i; return -1; } void print_table() { int i, j, k; printf("LL(1) Parsing Table:\n"); printf("NT/T\t"); for (j = 0; j < nterm; j++) printf("%c\t", t[j]); printf("$\t\n"); for (i = 0; i < nnt; i++) { printf("%c\t", nt[i]); for (j = 0; j <= nterm; j++) { for (k = 0; k < strlen(table[i][j]); k++) printf("%s ", prod[atoi(&table[i][j][k])]); printf("\t"); } printf("\n"); } } void parse(char *input) { char stack[MAX_NT+MAX_T]; int top = 0; stack[top] = '$'; stack[++top] = ntstart; char *p = input; while (*p != '\0') { char X = stack[top--]; if (is_t(X) || X == '$') { if (X == *p) { p++; } else { printf("Error: unexpected symbol %c\n", *p); return; } } else if (is_nt(X)) { int j = find_t(*p); int i = find_nt(X); if (table[i][j][0] == '\0') { printf("Error: no production for %c on input %c\n", X, *p); return; } else if (table[i][j][1] != '\0') { printf("Error: multiple productions for %c on input %c\n", X, *p); return; } else { char *q = prod[atoi(&table[i][j][0])]; int len = strlen(q); while (len > 0) { stack[++top] = q[--len]; } } } else { printf("Error: unknown symbol %c\n", X); return; } } char X = stack[top--]; if (X == ntstart && *p == '$') { printf("Parsing successful!\n"); } else { printf("Parsing failed!\n"); } } int main() { int i, j, k, l; printf("Enter the number of non-terminals: "); scanf("%d", &nnt); printf("Enter the non-terminals: "); for (i = 0; i < nnt; i++) scanf(" %c", &nt[i]); printf("Enter the start symbol: "); scanf(" %c", &ntstart); printf("Enter the number of terminals: "); scanf("%d", &nterm); printf("Enter the terminals: "); for (i = 0; i < nterm; i++) scanf(" %c", &t[i]); printf("Enter the number of productions: "); scanf("%d", &nprod); printf("Enter the productions:\n"); for (i = 0; i < nprod; i++) { scanf("%s", prod[i]); int idx = find_nt(prod[i][0]); for (j = 2; j < strlen(prod[i]); j++) { if (is_nt(prod[i][j])) { int k = find_nt(prod[i][j]); for (l = 0; l < nterm; l++) { if (first[k][l] == '1') select[i][l] = '1'; } if (first[k][nterm] == '1') { for (l = 0; l < nterm; l++) if (follow[idx][l] == '1') select[i][l] = '1'; } break; } else if (is_t(prod[i][j])) { int k = find_t(prod[i][j]); select[i][k] = '1'; break; } } } for (i = 0; i < nnt; i++) { for (j = 0; j < nterm; j++) { int flag = 0; for (k = 0; k < nprod; k++) { if (prod[k][0] == nt[i] && select[k][j] == '1') { if (flag == 1) { table[i][j][0] = '\0'; table[i][j][1] = '\0'; break; } else { table[i][j][0] = k + '0'; flag = 1; } } } if (flag == 0) table[i][j][0] = '\0'; } } for (i = 0; i < nnt; i++) { int flag = 0; for (k = 0; k < nprod; k++) { if (prod[k][0] == nt[i] && select[k][nterm] == '1') { if (flag == 1) { table[i][nterm][0] = '\0'; table[i][nterm][1] = '\0'; break; } else { table[i][nterm][0] = k + '0'; flag = 1; } } } if (flag == 0) table[i][nterm][0] = '\0'; } print_table(); char input[100]; printf("Enter the input string: "); scanf("%s", input); parse(input); return 0; } ``` 在实现过程中,我们需要先读入文法规则,然后根据文法规则计算FIRST集合、FOLLOW集合和SELECT集合,并构造预测分析表。接下来,我们可以对输入的符号串进行语法分析。 在这个示例中,我们使用了一个简单的错误处理机制,对于一些无法识别的符号、无法找到产生式和多个可能的产生式等情况,都会返回一个错误信息。如果符号串符合文法规则,我们会输出一条“Parsing successful!”的信息。 总之,这个示例可以帮助我们深入理解LL(1)分析法的实现过程,以及对文法规则的转换和处理。

相关推荐

最新推荐

recommend-type

语法分析器LL(1)文法(c语言)

该程序能求出任意给定的文法的所有非终极符和终极符的first集,所有非终极符的follow集,所有语句的select集,能求出能导空的非终极符集合。给定任意字符串该程序能判定出是否能接受
recommend-type

编译原理LL(1)语法分析实验报告.doc

通过完成预测分析法的语法分析程序,了解预测分析法和递归子程序法的区别和联系。使了解语法分析的功能,掌握语法分析程序设计的原理和构造方法,训练掌握开发应用程序的基本方法。
recommend-type

4 实验四:LR分析程序的设计与实现

1、了解LR(0)分析方法是严格的从左向右扫描,和自底向上的语法分析方法。 2、掌握LR(0)语法分析方法。
recommend-type

编译原理 LL(1)预测分析

本文将就编译原理中比较常用的一个表达式文法,通过预测...文中将为您提供如何通过FIRST、FOLLOW和SELECT集合来判断LL(1)方法,然后如何用预测分析法分析LL(1)方法的基本递归流程,以及如何用C语言来编程实现分析器。
recommend-type

语法分析器(基于mini-C的源程序)

语法分析器能够把源程序的符号流翻译成语法分析树,本次实验要求利用语法分析器自动生成yacc,翻译基于mini-C的源程序,并把生成的语法分析树描述加以显示。
recommend-type

STC89C51 简单时钟

STC89C51 简单时钟,叫你从基础开始学习单片机,
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

MATLAB归一化方法大比拼:5种方法,哪种最适合你的数据?

![MATLAB归一化方法大比拼:5种方法,哪种最适合你的数据?](https://www.finebi.com/wp-content/uploads/2019/11/FineBI%E8%A1%8C%E4%B8%9A%E9%A9%BE%E9%A9%B6%E8%88%B1-1024x510.png) # 1. MATLAB归一化概述 归一化是一种数据预处理技术,用于将数据缩放到特定范围内,从而消除不同特征之间的尺度差异。在MATLAB中,有各种归一化方法可用于不同类型的数据和应用程序。 归一化的主要目的是: - 提高模型的训练效率和准确性,通过消除特征之间的尺度差异,使模型能够更有效地学习
recommend-type

failed to register layer: ApplyLayer exit status 1 stdout: stderr: archive/tar: invalid tar header

很抱歉听到这个问题。这个错误通常是由于Docker镜像损坏或Docker存储库中缺少所需的图层引起的。您可以尝试以下几种方法来解决这个问题: 1. 清理Docker镜像和容器:使用命令“docker system prune”清理不再使用的Docker对象。 2. 检查Docker存储库:确保您正在使用可靠的Docker存储库,并检查是否存在所有必需的图层。 3. 重新下载Docker镜像:如果您确定问题是由于损坏的Docker镜像引起的,则可以尝试重新下载Docker镜像。 4. 更新Docker版本:如果您使用的是旧版Docker,则可能会出现此问题。尝试更新到最新版本的Docke
recommend-type

Linux系统常用操作命令大全手册

附件是Linux系统常用操作命令大全手册,是 markdown格式,其中覆盖了Linux系统管理、文件操作、网络配置等多个方面,都是日常工作中非常常用的命令,欢迎大家下载学习使用!