制作一个简单的C语言词法分析程序_用c语言编写词法分析程序-CSDN博客文章浏览阅读276次。C语言的程序中,有很单词多符号和保留字。一些单词符号还有对应的左线性文法。所以我们需要先做出一个单词字符表,给出对应的识别码,然后跟据对应的表格来写出程序。_用c语言编写词法分析程序https://blog.csdn.net/lijj0304/article/details/134078944前置程序词法分析器参考这个帖子⬆️
1.程序目标
递归下降实现的语法分析程序,程序可以识别词法分析程序的输出文件中的二元序列,拼凑出用户输入的算式,然后通过递归下降的方式从中识别算术表达式是否正确,在错误位置输出提示。算式的语法如下:
G[S]:S→V=E E→TE′ E′→ATE′|ε T→FT′ T′→MFT′|ε F→ (E)|i A→+|-M→*|/ V→i
2.程序设计
程序会分析analyze文件,根据二元式拼凑出原本的输入str,然后把算式中的变量转换成i,同时在结尾处加上结束符号#,方便运算。同时程序还设计了一个全局变量flag用于标记当前递归下降分析器的状态,如果出错则会把flag置为1。
完整的程序运行顺序如下:
- 读入分析的二元式获得用户输入
- 转换变量,加上结束符
- 递归下降分析,输出结论
3.递归下降详细设计
首先我根据给定的语法,计算处所需要用到的first集和follow集
first | follow | |
---|---|---|
S | i | # |
E | (, i | #, ) |
E’ | +, -, ε | #, ) |
T | (, i | +, -, #, ) |
T’ | *, /, ε | +, -, #, ) |
F | (, i | *, /, +, -, #, ) |
A | +, - | (, i |
M | *, / | (, i |
V | i | = |
S的递归下降分析程序设计:
E的递归下降分析程序设计:
E’的递归下降分析程序设计:
T的递归下降分析程序设计:
T’的递归下降程序设计:
F的递归下降程序设计:
A的递归下降程序设计:
M的递归下降程序设计:
V的递归下降程序设计:
4.完整程序
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX_LEN 1000
char str[MAX_LEN];
int i, j, flag;
void S();
void E();
void E1();
void T();
void T1();
void F();
void A();
void M();
void V();
void S() {
if(flag == 0) {
printf("S->");
if(str[i] == 'i') {
V();
if(flag == 0 && str[i] == '=') {
i++;
E();
}
else {
flag = 1;
printf("error\n");
}
}
else {
flag = 1;
printf("error\n");
}
}
}
void E() {
if(flag == 0) {
printf("E->");
if(str[i] == '(' || str[i] == 'i') {
T();
if(flag == 0) {
if(str[i] == '+' || str[i] == '-')
E1();
else if(str[i] == ')' || str[i] == '#')
return;
else {
flag = 1;
printf("error\n");
}
}
}
else {
flag = 1;
printf("error\n");
}
}
}
void E1() {
if(flag == 0) {
printf("E'->");
if(str[i] == '+' || str[i] == '-') {
A();
if(flag == 0) {
if(str[i] == '(' || str[i] == 'i') {
T();
if(flag == 0){
if(str[i] == '+' || str[i] == '-')
E1();
else if(str[i] == ')' || str[i] == '#')
return;
else {
flag = 1;
printf("error\n");
}
}
}
else{
flag = 1;
printf("error\n");
}
}
}
else if(str[i] == ')' || str[i] == '#')
return;
else {
flag = 1;
printf("error\n");
}
}
}
void T() {
if(flag == 0) {
printf("T->");
if(str[i] == '(' || str[i] == 'i') {
F();
if(flag == 0) {
if(str[i] == '*' || str[i] == '/')
T1();
else if(str[i] == '+' || str[i] == '-' || str[i] == ')' || str[i] == '#')
return;
else {
flag = 1;
printf("error\n");
}
}
}
else {
flag = 1;
printf("error\n");
}
}
}
void T1() {
if(flag == 0) {
printf("T'->");
if(str[i] == '*' || str[i] == '/') {
M();
if(flag == 0) {
F();
if(flag == 0)
T1();
}
}
else if(str[i] == '+' || str[i] == '-' || str[i] == ')' || str[i] == '#')
return;
else {
flag = 1;
printf("error\n");
}
}
}
void F() {
if(flag == 0){
printf("F->");
if(str[i] == '(') {
i++;
if(str[i] == '(' || str[i] == 'i') {
E();
if(flag == 0) {
if(str[i] == ')')
i++;
else {
flag = 1;
printf("error\n");
}
}
}
else {
flag = 1;
printf("error\n");
}
}
else if(str[i] == 'i') {
i++;
}
else {
flag = 1;
printf("error\n");
}
}
}
void A() {
if(flag == 0) {
printf("A->");
if(str[i] == '+' || str[i] == '-')
i++;
else {
flag = 1;
printf("error\n");
}
}
}
void M() {
if(flag == 0) {
printf("M->");
if(str[i] == '*' || str[i] == '/')
i++;
else {
flag=1;
printf("error\n");
}
}
}
void V() {
if(flag == 0){
printf("V->");
if(str[i] == 'i')
i++;
else{
flag = 1;
printf("error\n");
}
}
}
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);
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] = '#', input[j] = '#';
fclose(fp);
flag = 0, i = 0;
S();
if(str[i] == '#' && flag == 0) {
printf("end\n");
printf("Gramma legal: %s\n", str);
}
else
printf("Gramma illegal\n");
}
return 0;
}