递归下降法判断算术表达式的正确性 c

本文档介绍了如何使用递归下降法来实现对算术表达式的语法分析,目的是判断给定的表达式是否符合文法规则。首先,将初始文法转换为LL(1)文法,然后编写相应的分析程序。主函数通过读取文件中的算术表达式,调用递归下降分析函数进行语法检查,并对错误表达式提供详细错误信息。程序的输入和输出分别存储在两个文件中,对于无效的表达式,程序会指出错误位置并输出错误提示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

递归下降法判断算术表达式的正确性

要求

实验二 递归下降法判断算术表达式的正确性
学时数:2-4
一、实验目的和要求
1、 理解自顶向下语法分析方法;
2、 用递归下降技术实现语法分析器;

二、实验内容
算术表达式的文法是G[E]:
E→E+T| E-T| T
T→TF| T/F| F
F→(E)| i
用递归下降分析法按文法G[E]对算术表达式(包括+、-、
、/、()的算术表达式)进行语法分析,判断该表达式是否正确。

三、实验步骤
1、准备:阅读课本有关章节,将上述算术表达式的文法改造成LL(1)文法(即消除左递归和提取左公因子);
2、参考课件P52编写递归下降分析程序。

四、测试要求
1、 为降低难度,表达式中不含变量,只含单个无符号整数或i;
2、 如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好);
3、 测试用的表达式建议事先放在文本文件中,一行存放一个表达式,以分号结束。而语法分析程序的输出结果写在另一个文本文件中;
4、程序输入/输出示例:
输入如下表达式(以分号为结束)和输出结果:
(a)i; 或 1;
输出:正确
(b)i+i; 或 1+2;
输出:正确
(c)(i+i)i+i-(i+ii); 或 (1+2)3+4-(5+67);
输出:正确
(d)((i+i)*i+i; 或 ((1+2)*3+4;
输出:错误,缺少右括号
(e)i+i+i+(*i/i); 或 1+2+3+(*4/5)
输出:错误

1、语法分析所依据的文法;
G[E]:
E→E+T| E-T| T
T→T*F| T/F| F
F→(E)| i
2、给出消除左递归及提取左公因子的文法;
G’[E]:
E →  TE’
E’ → +TE’| -TE’|ε
T  →  FT’
T’→  *FT’|/FT’|ε
F  → (E)| i

主函数

文件数输入输出 (N)就表示为

#include <iostream>
#include <cstdio>
using namespace std;
char* lookahead;
char ch[100];
void E();
void EN();
void T();
void TN();
void F();
void matchs();
void error();
FILE* fin, * fout;

void matchs(char t)
{
	cout << "调用matchss当前*lookahead:" << *lookahead << endl;
	if (*lookahead == t)
		lookahead = lookahead + 1;
	else
		error();
}

void error() {

	cout << "调用error当前*lookahead:" << *lookahead << endl;

	fprintf(fout, "当前为*lookahead:'%c'", *lookahead);
	throw "  fail";



}
void E() {
	cout << "调用E当前*lookahead:" << *lookahead << endl;

	T();
	EN();
}
void T() {

	cout << "调用T当前*lookahead:" << *lookahead << endl;
	F();
	TN();
}
void F()
{
	cout << "调用F当前*lookahead:" << *lookahead << endl;

	if (*lookahead == '(')
	{
		matchs(*lookahead);
		E();
		if (*lookahead == ')') {
			matchs(*lookahead);
		}
		else
		{
			fprintf(fout, "括号不匹配    ");
			error();
		}

	}
	else if (*lookahead == 'i')
	{
		matchs('i');
	}
	else
		error();
}
void TN()
{
	cout << "调用TN当前*lookahead:" << *lookahead << endl;
	if (*lookahead == '*' || *lookahead == '/') {
		matchs(*lookahead);
		F();
		TN();
	}
}
void EN() {
	cout << "调用EN当前*lookahead:" << *lookahead << endl;

	if (*lookahead == '+' || *lookahead == '-')
	{
		matchs(*lookahead);
		T();
		EN();
		return;
	}

}
int main()
{
	
	//打开文件
	fin = fopen("input.txt", "r");
	fout = fopen("output.txt", "w+");


	while (fscanf(fin, "%s", ch) != EOF) {//从文件读取

		lookahead = ch;
		//捕获异常
		try {
			E();
			if (*lookahead == ';')
				fprintf(fout, "Sussess  \n");
			else
				error();
		}
		catch (const char* msg) {
			fprintf(fout, "%s\n", msg);
		}
		cout << endl << endl;
	}

	fclose(fin);
	fclose(fout);
}

输入

input.txt

i;
i+i;
(i+i)*i+i-(i+i*i);
((i+i)*i+i;
i+i+i+(*i/i);

输出

output.txt

Sussess  
Sussess  
Sussess  
括号不匹配    当前为*lookahead:';'  fail
当前为*lookahead:'*'  fail
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值