语法分析器c语言 递归子程序,RecursiveSubroutine

RecursiveSubroutine

介绍

编译原理语法分析——递归下降子程序类,C++实现。

实验说明

一、实验目标

分别采用自顶向下和自底向上两种语法分析方法,编制一个语法分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析实验内容。

二、实验内容

选取一种自顶向下语法分析方法(递归子程序、LL分析法)和一种自底向上语法分析法(算符优先分析、LR分析方法)设计语法分析器,并对简单语言进行语法分析。

2.1 待分析的简单语言的语法

用扩充的BNF表示如下:

⑴::=beginend

⑵::={;}

⑶::=

⑷::=ID:=

⑸::={+ | -}

⑹::={* | /

⑺::=ID | NUM | ()

用上下文无关文法表示如下:

P→begin SList end

SList→S{;S}

S→A

A→ID:=E

E→E+T|E-T|T

T→T*F|T/F|F

F→(E)|ID|NUM

2.2 实验要求说明

输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出“error”。

例如:

输入 begin a:=9; x:=23; b:=a+x end #

输出 success!

输入 x:=a+bc end #

输出 error

三、实验报告

实验结束需要提交实验报告,实验报告需要包含自顶向下和自底向上两种分析程序算法(可以用流程图表示)和源代码,以及测试结果截图以及相关分析(需要设计至少10个不同的测试用例)。两种不同算法用两个文档分别保存。

实验过程

改为LL(1)文法

P→begin SList end

SList→S{;S}

S→A

A→ID:=E

E→TE’

E’→BTE’|

B→+|-

T→FT’

T’→CFT’|

C→*|/

F→(E)|ID|NUM

递归子程序

参看项目代码

开发工具

VS2015

依赖

参与贡献

Fork 本仓库

新建 Feat_xxx 分支

提交代码

新建 Pull Request

码云特技

使用 Readme_XXX.md 来支持不同的语言,例如 Readme_en.md, Readme_zh.md

GVP 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
递归下降分析法 一、实验目的: 根据某一文法编制调试递归下降分析程序,以便对任意输入的符号串进行分析。本次实验的目的主要是加深对递归下降分析法的理解。 二、实验说明 1、递归下降分析法的功能 词法分析器的功能是利用函数之间的递归调用模拟语法树自上而下的构造过程。 2、递归下降分析法的前提 改造文法:消除二义性、消除左递归、提取左因,判断是否为LL(1)文法, 3、递归下降分析法实验设计思想及算法 为G的每个非终结符号U构造一个递归过程,不妨命名为U。 U的产生式的右边指出这个过程的代码结构: (1)若是终结符号,则和向前看符号对照, 若匹配则向前进一个符号;否则出错。 (2)若是非终结符号,则调用与此非终结符对应的过程。当A的右部有多个产生式时,可用选择结构实现。 三、实验要求 (一)准备: 1.阅读课本有关章节, 2.考虑好设计方案; 3.设计出模块结构、测试数据,初步编制好程序。 (二)上课上机: 将源代码拷贝到机上调试,发现错误,再修改完善。第二次上机调试通过。 (三)程序要求: 程序输入/输出示例: 对下列文法,用递归下降分析法对任意输入的符号串进行分析: (1)E->eBaA (2)A->a|bAcB (3)B->dEd|aC (4)C->e|dc 输出的格式如下: (1)递归下降分析程序,编制人:姓名,学号,班级 (2)输入一以#结束的符号串:在此位置输入符号串例如:eadeaa# (3)输出结果:eadeaa#为合法符号串 注意: 1.如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好); 2.对学有余力的同学,可以详细的输出推导的过程,即详细列出每一步使用的产生式。 (四)程序思路 0.定义部分:定义常量、变量、数据结构。 1.初始化:从文件将输入符号串输入到字符缓冲区中。 2.利用递归下降分析法分析,对每个非终结符编写函数,在主函数中调用文法开始符号的函数。
自顶向下递归下降子程序语法分析器(Top-Down Recursive Descent Parser)是一种简单的解析方法,它从输入的最顶层开始,并逐步解析整个句。以下是一个基本的C语言实现例,使用LL(1)分析法,用于解析简单的算术表达式: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> typedef enum { PLUS, MINUS, NUM } Operation; // 用于存储符号和操作 struct Token { char symbol; Operation op; }; // 定义表达式的结构体 struct Expression { struct Expression *left, *right; Operation op; }; // 递归解析函数 struct Expression *parse_expression(char* input); struct Token *parse_token(char* input); int main() { char input[] = "3 + 4 * 2"; struct Expression *expr = parse_expression(input); printf("Parsed expression: %d\n", expr->left->value); // 假设我们有一个方法访问值 free(expr); return 0; } // 解析一个算术操作符或数字 struct Token *parse_token(char* input) { if (isdigit(input[0])) { char num; num = input - '0'; if (input == '\0') return (struct Token) { .symbol = 'NUM', .op = NUM }; num = input - '0'; input += 2; return (struct Token) { .symbol = 'NUM', .op = NUM, .value = atoi(num) }; } else if (input == '+' || input == '-') { input++; return (struct Token) { .symbol = input, .op = input == '+' ? PLUS : MINUS }; } return NULL; } // 解析一个表达式 struct Expression *parse_expression(char* input) { struct Token token = parse_token(input); if (!token.symbol) return NULL; // 无效输入 struct Expression *expr = malloc(sizeof(struct Expression)); expr->op = token.op; // 分别处理加减号后的部分 switch (expr->op) { case PLUS: expr->left = parse_expression(input); input = expr->left->symbol == 'NUM' ? input : input + 1; expr->right = parse_expression(input); break; case MINUS: expr->left = parse_expression(input); input = expr->left->symbol == 'NUM' ? input : input + 1; expr->right = parse_expression(input); break; default: break; } return expr; } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值