#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include<string.h>
#include<fstream>
#include<map>
using namespace std;
const int N=10010;
string words[N];
string vlaue[N];
int wordsnums=0;
string KEYWORD[19]={"const","if","else","void","return","while","then","for","do", //关键字
"int","char","double","float","case","cin","cout","main","scanf","printf"};
char OPERATOR[8]={'+','-','*','/','>','<','=','!'}; //运算符
string OPERRATOR1[11]={"+","-","*","/",">","<","=","<=",">=","==","!="};
char FILTER[4]={' ','\t','\r','\n'}; //过滤符
//过滤字符值
/**判断是否为关键字**/
bool IsKeyword(string word){
for(int i=0;i<19;i++){
if(KEYWORD[i]==word){
return true;
}
}
return false;
}
/**判断是否为运算符**/
bool IsOperator(char ch){
for(int i=0;i<8;i++){
if(OPERATOR[i]==ch){
return true;
}
}
return false;
}
/**判断是否为过滤符**/
bool IsFilter(char ch){
for(int i=0;i<4;i++){
if(FILTER[i]==ch){
return true;
}
}
return false;
}
/**判断是否为大写字母**/
bool IsUpLetter(char ch){
if(ch>='A' && ch<='Z') return true;
return false;
}
/**判断是否为小写字母**/
bool IsLowLetter(char ch){
if(ch>='a' && ch<='z') return true;
return false;
}
/**判断是否为数字**/
bool IsDigit(char ch){
if(ch>='0' && ch<='9') return true;
return false;
}
/**返回每个字的值**/
template <class T>
int value(T *a,int n,T str){
for(int i=0;i<n;i++){
if(a[i]==str) return i;
}
return -1;
}
int value1(string str1,string a[])
{
for(int i=0;i<11;i++)
{
if(a[i]==str1) return i;
}
return true;
}
/**词法分析**/
void analyse(FILE * fpin){
char ch=' ';
string arr="";
while((ch=fgetc(fpin))!=EOF){
arr="";
if(IsFilter(ch)){} //判断是否为过滤符
else if(IsLowLetter(ch)){ //判断是否为关键字
while(IsLowLetter(ch)||IsDigit(ch)||IsUpLetter(ch)||ch=='_'){
arr += ch;
ch=fgetc(fpin);
}
//fseek(fpin,-1L,SEEK_CUR);
if(IsKeyword(arr)){
int flag;
flag=value(KEYWORD,19,arr);
switch(flag)
{
case 0: words[wordsnums]="CONSTTK";break;
case 1: words[wordsnums]="IFTK";break;
case 2: words[wordsnums]="ELSETK";break;
case 3: words[wordsnums]="VOIDTK";break;
case 4: words[wordsnums]="RETURNTK";break;
case 5: words[wordsnums]="WHILETK";break;
case 6: words[wordsnums]="THENTK";break;
case 7: words[wordsnums]="FORTK";break;
case 8: words[wordsnums]="DOTK";break;
case 9: words[wordsnums]="INTTK";break;
case 10: words[wordsnums]="CHARTK";break;
case 11:words[wordsnums]="DOUBLETK";break;
case 12: words[wordsnums]="FLOATTK";break;
case 13: words[wordsnums]="CASETK";break;
case 14: words[wordsnums]="CINTK";break;
case 15: words[wordsnums]="COUTTK";break;
case 16: words[wordsnums]="MAINTK";break;
case 17: words[wordsnums]="SCANFTK";break;
case 18:words[wordsnums]="PRINTFTK";break;
}
fseek(fpin,-1L,SEEK_CUR);
}
else
{
words[wordsnums]="IDENFR";
fseek(fpin,-1L,SEEK_CUR);
}
vlaue[wordsnums]=arr;
wordsnums++;
}
else if(IsDigit(ch)){ //判断是否为数字
while(IsDigit(ch)||(ch=='.'&&IsDigit(fgetc(fpin)))){
arr += ch;
ch=fgetc(fpin);
}
fseek(fpin,-1L,SEEK_CUR);
words[wordsnums]="INTCON";
vlaue[wordsnums]=arr;
wordsnums++;
}
else if(IsUpLetter(ch)||IsLowLetter(ch)||ch=='_'){
while(IsUpLetter(ch)||IsLowLetter(ch)||ch=='_'||IsDigit(ch)){
arr += ch;
ch=fgetc(fpin);
}
fseek(fpin,-1L,SEEK_CUR);
words[wordsnums]="IDENFR";
vlaue[wordsnums]=arr;
wordsnums++;
}
else if(IsOperator(ch))
{
do
{
arr+=ch;
ch=fgetc(fpin);
}while(IsOperator(ch)&&ch!='+');
int flag1;
flag1=value1(arr,OPERRATOR1);
switch(flag1)
{
case 0: words[wordsnums]="PLUS";break;
case 1: words[wordsnums]="MINU";break;
case 2: words[wordsnums]="MULT";break;
case 3: words[wordsnums]="DIV";break;
case 4: words[wordsnums]="GRE";break;
case 5: words[wordsnums]="LSS";break;
case 6: words[wordsnums]="ASSIGN";break;
case 7: words[wordsnums]="LEQ";break;
case 8: words[wordsnums]="GEQ";break;
case 9: words[wordsnums]="EQL";break;
case 10: words[wordsnums]="NEQ";}
fseek(fpin,-1L,SEEK_CUR);
vlaue[wordsnums]=arr;
wordsnums++;
}
else if(ch=='"')
{
ch=fgetc(fpin);
string str2;
while(ch!='"')
{
str2+=ch;
ch=fgetc(fpin);
}
words[wordsnums]="STRCON";
vlaue[wordsnums]=str2;
wordsnums++;
}
else if(ch==39)
{
ch=fgetc(fpin);
string str3;
while(ch!=39)
{
str3+=ch;
ch=fgetc(fpin);
}
words[wordsnums]="CHARCON";
vlaue[wordsnums]=str3;
wordsnums++;
}
else {
switch(ch){
case ';':
words[wordsnums]="SEMICN";
vlaue[wordsnums]=ch;
wordsnums++;
break;
case ',':
words[wordsnums]="COMMA";
vlaue[wordsnums]=ch;
wordsnums++;
break;
case '(':
words[wordsnums]="LPARENT";
vlaue[wordsnums]=ch;
wordsnums++;
break;
case ')':
words[wordsnums]="RPARENT";
vlaue[wordsnums]=ch;
wordsnums++;
break;
case '[':
words[wordsnums]="LBRACK";
vlaue[wordsnums]=ch;
wordsnums++;
break;
case ']':
words[wordsnums]="RBRACK";
vlaue[wordsnums]=ch;
wordsnums++;
break;
case '{':
words[wordsnums]="LBRACE";
vlaue[wordsnums]=ch;
wordsnums++;
break;
case '}':
words[wordsnums]="RBRACE";
vlaue[wordsnums]=ch;
wordsnums++;
break;
default :{}}
}
}
}
int q;
map <string,int>Choose;
void digui0(); //<字符串>
void digui1(); //<程序>
void digui2(); //<常量说明>
void dugui3(); //<常量定义>
void digui4(); //<无符号整数>
void digui5(); //<整数>
void digui6(); //<声明头部>
void digui7(); //<变量说明>
void digui8(); //<变量定义>
void digui9(); //<有返回值函数定义>
void digui10(); //<无返回值函数定义>
void digui11(); //<复合语句>
void digui12(); //<参数表>
void digui13(); //<主函数>
void digui14(); //<表达式>
void digui15(); //<项>
void digui16(); //<因子>
void digui17(); //<语句>
void digui18(); //<赋值语句>
void digui19(); //<条件语句>
void digui20(); //<条件>
void digui21(); //<循环语句>
void digui22(); //<步长>
void digui234(); //<有无返回值函数调用语句>
void digui25(); //<值参数表>
void digui26(); //<语句列>
void digui27(); //<读语句>
void digui28(); //<写语句>
void digui29(); //<返回语句>
fstream fout("output.txt",ios::out);
void string_analyse()
{
q=0;
digui1();
return;
}
void output(string str)
{
if(words[q]==str)
{
fout<<words[q]<<" "<<vlaue[q]<<endl;
q++;
}
else cout<<"error"<<endl;
}
void digui0()
{
output("STRCON");
fout<<"<字符串>"<<endl;
}
void digui1()
{
//[<常量说明>][<变量说明>]{<有返回值函数定义>|<无返回值函数定义>}<主函数>
//常量说明:
if(words[q]=="CONSTTK") digui2();
//变量说明:
if((words[q]=="INTTK"||words[q]=="CHARTK")&&words[q+1]=="IDENFR"&&words[q+2]!="LPARENT")
{
digui7();
}
//有无返回值函数定义
while((words[q]=="VOIDTK"||words[q]=="CHARTK"||words[q]=="INTTK")&&words[q+1]=="IDENFR"&&words[q+2]=="LPARENT")
{
if(words[q]=="CHARTK"||words[q]=="INTTK") digui9();
else digui10();
}
//主函数
if((words[q]=="VOIDTK"||words[q]=="INTTK")&&words[q+1]=="MAINTK")
{
digui13();
}
if(q==wordsnums)
{
fout<<"<程序>"<<endl;
return;
}
else
{
cout<<"qerror"<<endl;
}
}
void digui3(); //距离太远重新声明
void digui2() //常量说明
{
//const<常量定义>;{ const<常量定义>;}
do
{
output("CONSTTK");
digui3();
output("SEMICN");
}while(words[q]=="CONSTTK");
fout<<"<常量说明>"<<endl;
}
void digui3() //常量定义
{
//int<标识符>=<整数>{,<标识符>=<整数>}
//char<标识符>=<字符>{,<标识符>=<字符>}
if(words[q]=="INTTK")
{
output("INTTK");output("IDENFR");output("ASSIGN");
digui5();//整数
while(words[q]=="COMMA")
{
output("COMMA");
output("IDENFR");
output("ASSIGN");
digui5();
}
}
if(words[q]=="CHARTK")
{
output("CHARTK");output("IDENFR");output("ASSIGN");output("CHARCON");
while(words[q]=="COMMA")
{
output("COMMA");output("IDENFR");output("ASSIGN");output("CHARCON");
}
}
fout<<"<常量定义>"<<endl;
}
void digui4()
{
//<非零数字>{<数字>}| 0
output("INTCON");
fout<<"<无符号整数>"<<endl;
}
void digui5()
{
//[+|-]<无符号整数>
if(words[q]=="PLUS") output("PLUS");
else if(words[q]=="MINU") output("MINU");
digui4();
fout<<"<整数>"<<endl;
}
void digui6()
{
//int<标识符> |char<标识符>
if(words[q]=="INTTK") output("INTTK");
else if(words[q]=="CHARTK") output("CHARTK");
output("IDENFR");
fout<<"<声明头部>"<<endl;
}
void digui7()
{
//<变量定义>;{<变量定义>;}
do
{
digui8();
output("SEMICN");
}while((words[q]=="INTTK"||words[q]=="CHARTK")&&words[q+1]=="IDENFR"&&words[q+2]!="LPARENT");
fout<<"<变量说明>"<<endl;
}
void digui8()
{
//<类型标识符>(<标识符>|<标识符>'['<无符号整数>']'){,(<标识符>|<标识符>'['<无符号整数>']' )}
//||<无符号整数>表示数组元素的个数,其值需大于0
//<类型标识符> ::= int | char
if(words[q]=="INTTK") output("INTTK");
else if(words[q]=="CHARTK") output("CHARTK");
output("IDENFR");
if(words[q]=="LBRACK")
{
output("LBRACK");
digui4();
output("RBRACK");
}
while(words[q]=="COMMA")
{
output("COMMA");
output("IDENFR");
if(words[q]=="LBRACK")
{
output("LBRACK");
digui4();
output("RBRACK");
}
}
fout<<"<变量定义>"<<endl;
}
void digui9()
{
//<声明头部>'('<参数表>')' '{'<复合语句>'}'
digui6();
output("LPARENT");
digui12();
output("RPARENT");
output("LBRACE");
digui11();
output("RBRACE");
fout<<"<有返回值函数定义>"<<endl;
}
void digui10()
{
//<无返回值函数定义> ::= void<标识符>'('<参数表>')''{'<复合语句>'}'
output("VOIDTK");
Choose[vlaue[q]]=1;
output("IDENFR");
output("LPARENT");
digui12();
output("RPARENT");
output("LBRACE");
digui11();
output("RBRACE");
fout<<"<无返回值函数定义>"<<endl;
}
void digui11()
{
//[<常量说明>][<变量说明>]<语句列>
if(words[q]=="CONSTTK") digui2();
if((words[q]=="INTTK"||words[q]=="CHARTK")&&words[q+1]=="IDENFR"&&words[q+2]!="LPARENT")
{
digui7();
}
digui26();
fout<<"<复合语句>"<<endl;
}
void digui12()
{
//<类型标识符><标识符>{,<类型标识符><标识符>}| <空>
if(words[q]!="RPARENT")
{
if(words[q]=="INTTK") output("INTTK");
else if(words[q]=="CHARTK") output("CHARTK");
output("IDENFR");
while(words[q]=="COMMA")
{
output("COMMA");
if(words[q]=="INTTK") output("INTTK");
else if(words[q]=="CHARTK") output("CHARTK");
output("IDENFR");
}
}
fout<<"<参数表>"<<endl;
}
void digui13()
{
//<主函数> ::= void main‘(’‘)’ ‘{’<复合语句>‘}’
output("VOIDTK");output("MAINTK");output("LPARENT");output("RPARENT");
output("LBRACE");
digui11();
output("RBRACE");
fout<<"<主函数>"<<endl;
}
void digui14()
{
//<表达式> ::= [+|-]<项>{<加法运算符><项>} //[+|-]只作用于第一个<项>
if(words[q]=="PLUS") output("PLUS");
else if(words[q]=="MINU") output("MINU");
digui15();
while(words[q]=="PLUS"||words[q]=="MINU")
{
if(words[q]=="PLUS") output("PLUS");
else if(words[q]=="MINU") output("MINU");
digui15();
}
fout<<"<表达式>"<<endl;
}
void digui15()
{
//<项> ::= <因子>{<乘法运算符><因子>}
digui16();
while(words[q]=="MULT"||words[q]=="DIV")
{
if(words[q]=="MULT") output("MULT");
else if(words[q]=="DIV") output("DIV");
digui16();
}
fout<<"<项>"<<endl;
}
void digui16()
{
//<因子> ::= <标识符>|<标识符>'['<表达式>']'
//|'('<表达式>')'|<整数>|<字符>|<有返回值函数调用语句>
if(words[q]=="IDENFR")
{
if(words[q+1]=="LBRACK")
{
output("IDENFR");
output("LBRACK");
digui14();
output("RBRACK");
}
else if(words[q+1]=="LPARENT") digui234();
else output("IDENFR");
}
else if(words[q]=="LPARENT") {output("LPARENT");digui14();output("RPARENT");}
else if(words[q]=="INTCON"||words[q]=="PLUS"||words[q]=="MINU") digui5();
else if(words[q]=="CHARCON") output("CHARCON");
fout<<"<因子>"<<endl;
}
void digui17()
{
//<语句> ::= <条件语句>|<循环语句>| '{'<语句列>'}'| <有返回值函数调用语句>;
// |<无返回值函数调用语句>;|<赋值语句>;|<读语句>;|<写语句>;|<空>;|<返回语句>;
if(words[q]=="IFTK") digui19();
else if(words[q]=="WHILETK"||words[q]=="DOTK"||words[q]=="FORTK") digui21();
else if(words[q]=="LBRACE")
{
output("LBRACE");
digui26();
output("RBRACE");
}
else if(words[q]=="IDENFR")
{
if(words[q+1]=="LPARENT") {digui234();output("SEMICN");}//有无返回值函数调用语句
else{
digui18();
output("SEMICN"); //赋值语句
}
}
else if(words[q]=="SCANFTK")
{
digui27();output("SEMICN");
}
else if(words[q]=="PRINTFTK")
{
digui28();output("SEMICN");
}
else if(words[q]=="SEMICN") output("SEMICN");
else if(words[q]=="RETURNTK")
{
digui29();output("SEMICN");
}
fout<<"<语句>"<<endl;
}
void digui18()
{
//<赋值语句> ::= <标识符>=<表达式>|<标识符>'['<表达式>']'=<表达式>
output("IDENFR");
if(words[q]=="LBRACK")
{
output("LBRACK");
digui14();
output("RBRACK");
}
output("ASSIGN");
digui14();
fout<<"<赋值语句>"<<endl;
}
void digui19()
{
//<条件语句> ::= if '('<条件>')'<语句>[else<语句>]
output("IFTK");
output("LPARENT");
digui20();
output("RPARENT");
digui17();
if(words[q]=="ELSETK")
{
output("ELSETK");
digui17();}
fout<<"<条件语句>"<<endl;
}
void digui20()
{
// <表达式><关系运算符><表达式> (整型表达式之间才能进行关系运算)
//<表达式> (表达式为整型,其值为0条件为假,值不为0时条件为真)
digui14();
if(words[q]=="LSS"||words[q]=="LEQ"||words[q]=="GRE"||words[q]=="GEQ"
||words[q]=="EQL"||words[q]=="NEQ")
{
output(words[q]);
digui14();
}
fout<<"<条件>"<<endl;
}
void digui21()
{
//<循环语句> ::= while '('<条件>')'<语句>
//| do<语句>while '('<条件>')'
//|for'('<标识符>=<表达式>;<条件>;<标识符>=<标识符>(+|-)<步长>')'<语句>
if(words[q]=="WHILETK")
{
output("WHILETK");
output("LPARENT");
digui20();
output("RPARENT");
digui17();
}
else if(words[q]=="DOTK")
{
output("DOTK");
digui17();
output("WHILETK");
output("LPARENT");
digui20();
output("RPARENT");
}
else if(words[q]=="FORTK")
{
output("FORTK");output("LPARENT");output("IDENFR");output("ASSIGN");digui14();output("SEMICN");
digui20();output("SEMICN");
output("IDENFR");output("ASSIGN");output("IDENFR");
if(words[q]=="PLUS") output("PLUS");
else if(words[q]=="MINU") output("MINU");
digui22();
output("RPARENT");
digui17();
}
fout<<"<循环语句>"<<endl;
}
void digui22()
{
//<步长>::= <无符号整数>
digui4();
fout<<"<步长>"<<endl;
}
void digui234()
{
//<标识符>'('<值参数表>')'
int chooseresult=Choose[vlaue[q]];
output("IDENFR");
output("LPARENT");
digui25();
output("RPARENT");
if(chooseresult==1) fout<<"<无返回值函数调用语句>"<<endl;
else fout<<"<有返回值函数调用语句>"<<endl;
}
void digui25()
{
//<值参数表> ::= <表达式>{,<表达式>}|<空>
if(words[q]!="RPARENT")
{
digui14();
while(words[q]=="COMMA")
{
output("COMMA");
digui14();
}
}
fout<<"<值参数表>"<<endl;
}
void digui26()
{
//{<语句>}
while(words[q]!="RBRACE")
{
digui17();
}
fout<<"<语句列>"<<endl;
}
void digui27()
{
//<读语句> ::= scanf '('<标识符>{,<标识符>}')'
output("SCANFTK");
output("LPARENT");
output("IDENFR");
while(words[q]=="COMMA")
{
output("COMMA");
output("IDENFR");
}
output("RPARENT");
fout<<"<读语句>"<<endl;
}
void digui28()
{
//<写语句> ::= printf '(' <字符串>,<表达式> ')'
//| printf '('<字符串> ')'| printf '('<表达式>')'
output("PRINTFTK");
output("LPARENT");
if(words[q]=="STRCON") digui0();
else digui14();
if(words[q]=="COMMA") {output("COMMA");digui14();}
output("RPARENT");
fout<<"<写语句>"<<endl;
}
void digui29()
{
//<返回语句> ::= return['('<表达式>')']
output("RETURNTK");
if(words[q]=="LPARENT")
{
output("LPARENT");
digui14();
output("RPARENT");
}
fout<<"<返回语句>"<<endl;
}
int main()
{
FILE *fpin=fopen("testfile.txt","r");
if(NULL==fpin) cout<<"false"<<endl;
analyse(fpin);
string_analyse();
fclose(fpin);
return 0;
}
编译原理实验语法分析器
于 2022-05-12 20:52:33 首次发布