LL(1)语法分析程序设计与实现

制作一个简单的C语言词法分析程序_用c语言编写词法分析程序-CSDN博客文章浏览阅读322次。C语言的程序中,有很单词多符号和保留字。一些单词符号还有对应的左线性文法。所以我们需要先做出一个单词字符表,给出对应的识别码,然后跟据对应的表格来写出程序。_用c语言编写词法分析程序https://blog.csdn.net/lijj0304/article/details/134078944

前置程序词法分析器参考这个帖子⬆️

1.程序目标

制作一个LL(1)语法分析程序,程序可以识别词法分析器的输出文件中的二元序列,拼凑出用户输入。通过表驱动程序,实现赋值语句的LL(1)文法的LL(1)分析过程。算式的语法如下:

G[S]: S→V=E        E→TE′        E′→ATE|ε        T→FT′        T′→MFT′|ε        F→ (E)|i        A→+|-M→*|/        V→i

2.程序设计

我根据给定的语法,计算处所需要用到的first集和follow集,接着做select集,然后可以做出LL(1)分析表:

i

+

-

*

/

(

)

#

S

SV=E

E

ETE’

ETE’

E’

E’ATE’

E’ATE’

E’ ε

E’ ε

T

TFT’

TFT’

T’

T’ ε

T’ ε

T’MFT’

T’MFT’

T’ ε

T’ ε

F

Fi

F(E)

M

M*

M/

A

A+

A-

V

Vi

LL(1)的语法分析部分使用栈的思想来实现,定义了一个字符串的栈stack,LL1分析过程中产生的串存储在栈中,同时对于输入串有一个定位指针,栈顶元素和指针指向的字符比对,一样则栈顶元素出栈,指针往后移动。 

下面是程序LL(1)分析流程图

 

3.完整程序 

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX_LEN 1000
char str[MAX_LEN];
char stack[MAX_LEN];
int top = 0;

int LL1(char *str, char *stack) {
    int i = 0;
    while(str[i] != '#') {
		if(top < 0) return 0;
		if(stack[top] == str[i]) {
			printf("%c -> ", stack[top]);
			top--;
			i++;
		}
        else if(stack[top] == 'S') {
			if(str[i] == 'i') {
				stack[top++] = 'E';
				stack[top++] = '=';
				stack[top] = 'V';
			}
			else return 0;
		}
		else if(stack[top] == 'E') {
			if(str[i] == 'i') {
				stack[top++] = 'e';
				stack[top] = 'T';
			}
			else if(str[i] == '(') {
				stack[top++] = 'e';
				stack[top] = 'T';
			}
			else return 0;
		}
		else if(stack[top] == 'e') {
			if(str[i] == '+') {
				stack[top++] = 'e';
				stack[top++] = 'T';
				stack[top] = 'A';
			}
			else if(str[i] == '-') {
				stack[top++] = 'e';
				stack[top++] = 'T';
				stack[top] = 'A';
			}
			else if(str[i] == ')' || str[i] == '#') {
				printf("%c -> ", str[i]);
				top--;
			}
			else return 0;
		}
		else if(stack[top] == 'T') {
			if(str[i] == 'i') {
				stack[top++] = 't';
				stack[top] = 'F';
			}
			else if(str[i] == '(') {
				stack[top++] = 't';
				stack[top] = 'F';
			}
			else return 0;
		}
		else if(stack[top] == 't') {
			if(str[i] == '*') {
				stack[top++] = 't';
				stack[top++] = 'F';
				stack[top] = 'M';
			}
			else if(str[i] == '/') {
				stack[top++] = 't';
				stack[top++] = 'F';
				stack[top] = 'M';
			}
			else if(str[i] == '+' || str[i] == '-' || str[i] == ')' || str[i] == '#') {
				printf("%c -> ", str[i]);
				top--;
			}
			else return 0;
		}
		else if(stack[top] == 'F') {
			if(str[i] == 'i') 
				stack[top] = 'i';
			else if(str[i] == '(') {
				stack[top++] = ')';
				stack[top++] = 'E';
				stack[top] = '(';
			}
			else return 0;
		}
		else if(stack[top] == 'A') {
			if(str[i] == '+')
				stack[top] = '+';
			else if(str[i] == '-')
				stack[top] = '-';
			else return 0;
		}
		else if(stack[top] == 'M') {
			if(str[i] == '*')
				stack[top] = '*';
			else if(str[i] == '/')
				stack[top] = '/';
			else return 0;
		}
		else if(stack[top] == 'V') {
			if(str[i] == 'i') 
				stack[top] = 'i';
			else return 0;
		}
		else return 0;
    }
	return 1;
}

int main() {
	for(int m = 1; m <= 4; m++) {
		printf("test%d:\n", m);
		char txt[] = "./lexical/analyze";
		char num[6];
		sprintf(num, "%d.txt", m);
		strcat(txt, num);
		FILE *fp = fopen(txt, "r");
		char buf[MAX_LEN] = "";
		char input[MAX_LEN] = "";
		fgets(buf, MAX_LEN, fp);
		int i = 0, j = 0;
		for(int k = 0; k < strlen(buf); k++) {
			if(buf[k] == '1' && buf[k+1] == ',') {
				str[i++] = 'i';
				k += 3;
				while(1) {
					if(buf[k] == ')' && buf[k+1] == ' ')
						break;
					input[j++] = buf[k++];
				}
				continue;
			}
			if(buf[k] == ',' && buf[k+1] == ' ') {
				k += 2;
				while(1) {
					if(buf[k] == ')' && buf[k+1] == ' ')
						break;
					str[i++] = buf[k];
					input[j++] = buf[k++];
				}
			}
		}
		printf("Input scentence: %s\n", input);
		str[i] = '#';
		fclose(fp);
		stack[0] = 'S', top = 0;
		int flag = LL1(str, stack);
		if(flag == 1) {
			printf("end\n");
			printf("Gramma legal: %s\n", str);
		}
		else {
			printf("error\n");
			printf("Gramma illegal\n");
		}
	}
    return 0;
}

 4.运行测试

  • 18
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哆啦叮当

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值