递归下降 ll(1) 型文法 识别二元组文法分析
#include <stdio.h>
#include <string.h>FILE* fp;
FILE* fa2;char* str = new char[1200]; // 循环读取文件,分200字节读取char* peek;// 表格
typedef struct table {char* sign;char* kind;char* message;
} signtable;signtable* list; // 数据表
int cnt=0; // 当前读取表行
int cntv2=0; // 递归下降时数据推进下一个// 匹配字符
int match(char p) {if(*peek==p) {peek++;return 1;} else {printf("%d\n",peek-str);return 0;}}int parseA() {if(*peek=='a') {match('a');return 1;
// return match('a');} else {printf("发现错误\n");return 0;}
}
int parseB() {if(*peek=='c') {return match('c');} else if(*peek=='b') {return 1;}return 0;
}int parseS() {if(*peek=='a') {return parseA()&&match('a')&&parseS();} else if(*peek=='b'||*peek=='c') {return parseB()&&match('b')&&parseS();} else if(*peek=='d') {return match('d');}// if(1) { // 是目标字符串
// return 1;
// }return 0; // 如果没有命中
}// 比较后进入下一个记号
int matchv2(char ch) {if(*peek==ch) {cntv2++;peek=&list[cntv2].sign[0];return 1;}return 0;
}// 一个声明,因为出现了循环调用
int parseE();int parseF() {if(*peek=='n') {matchv2('n');return 1;} else if(*peek=='l') {return matchv2('l')&&parseE()&&matchv2('r');}return 0;
}
// 待定
int parseT1() {if(*peek=='t') {matchv2('t');return parseF()&&parseT1();} else if(*peek=='d') {matchv2('d');return parseF()&&parseT1();} else {return 1;}}// E产生函数追加,顺藤摸瓜
int parseT() {return parseF()&&parseT1();
}// 待定
int parseE1() {if(*peek=='p'){matchv2('p');return parseT()&&parseE1();} else if(*peek=='s'){matchv2('s');return parseT()&&parseE1();}else{return 1;}
// return 0;
// return 1;
}int parseE() {
// if(*peek==''){return parseT()&&parseE1();
// }
}// 初始化表格
void init() {list = new signtable[500];for(int i=0; i<500; i++) {list[i].kind = new char[30];list[i].message = new char[15];list[i].sign = new char[5];}}
// 表格写入数据
void split() {int pos=0;for(int k=0;; k++) {if(str[k]==',') {pos=k;break;}}int i=0;for(; i<pos; i++) {list[cnt].kind[i]=str[i];}list[cnt].kind[i]='\0';i=pos+1;for(; str[i]!='\0'; i++) {// 从 0 开始复制字符list[cnt].message[i-pos-1]=str[i];}list[cnt].message[i-pos-1]='\0';list[cnt].sign[0]=list[cnt].kind[0];list[cnt].sign[1]='\0';cnt++;}int main() {init();fp = fopen("input.txt", "r");fa2 = fopen("output.txt", "w");int check=0;// 分割词语
// while (fgets(str, 200, fp) != NULL) {// 利用scanf 读取吸收回车,而希冀里不能执行 '\n'的比较while (fscanf(fp, "%s", str) != EOF) {// 处理回车,有些回车读取会影响代码结果if (str[0] == '\n' && strlen(str) == 0) {continue;} else if (str[strlen(str) - 1 ] == '\n') { // 发现文末回车str[strlen(str) - 1 ] = '\0';}// 剥离成函数使用split();}for(int i=0; i<cnt; i++) {printf("%s\t%s\t%s\n",list[i].kind,list[i].message,list[i].sign);}peek = str;peek = &list[0].sign[0];// check = parseS();check = parseE();// 像 parseS() 一样,直接->改match 系列, 然后数据再说// 直接面向类型进行递归下降// fprintf(fa2,"%s\n",str);if(check==1) {fprintf(fa2,"true\n");printf("true\n");} else {fprintf(fa2,"false\n");printf("false\n");}fclose(fa2);fclose(fp);return 0;
}