这是对之前的代码的扩充。
#include <bits/stdc++.h>
using namespace std;
/*
变量说明:
line 从终端读入的字符串; 当前所指位置在计数器 p
token 为存放的单词自身字符串;当前所指位置在计数器 m
number 整型常数
sym 每个单词符号种类
*/
enum symbol
{
period=0,
ident=1,
number=2,
Plus=3,
Minus=4,
times=5,
slash=6,
eql=7,
neq=8,
lss=9,
leq=10,
gtr=11,
geq=12,
lparen=13,
rparen=14,
semicolon=15,
becomes=16,
beginsym=17,
endsym=18,
ifsym=19,
thensym=20,
whilesym=21,
dosym=22,
note=23,
elsesym=24,
intsym=25,
doublesym=26,
floatsym=27,
longsym=28,
comma=29,
nil=30,
};
char line[100],token[10],ch;
enum symbol sym;
int p,m, num;
char *word[11]= {"begin","end", "if","then","while","do","else","int","double","float","long"};
int Err;
bool flag=true;
void getsym();
int block();
void error(int i);
void statement();
void expression();
void term();
void factor();
void condition();
void Relational_operator();
void is_ident();
vector<string> define;
int main()
{
//freopen("tt.txt","r",stdin);
//读了字符串, 直到遇.结束
p=0;
printf("\n please input a string(end with '.'): ");
do
{
scanf("%c",&ch);
line[p++]=ch;
}
while(ch!='.');
line[p++]='\0';
define.clear();
//逐个单词扫描;
Err = 0;
p=0;
getsym(); //当前扫描的单词存放在sym中
block();
if ((sym==0)&&(Err==0))
printf("syntax parses success!\n");
return 0;
}
void printSym(enum symbol sym)
{
/************************************************
**** ****
**** TODO: 输出单词 ****
**** ****
*************************************************/
switch(sym)
{
case period:
return;
case number:
printf("( number,%-10d)\n",num);
break;
case nil:
printf("you have input a wrong string\n");
break;
case note:
printf("this is notes\n");
break;
case Plus:
printf("( Plus,%-10s)\n","+");
break;
case Minus:
printf("( Minus,%-10s)\n","-");
break;
case times:
printf("( times,%-10s)\n","*");
break;
case slash:
printf("( slash,%-10s)\n","/");
break;
case eql:
printf("( eql,%-10s)\n","=");
break;
case neq:
printf("( neq,%-10s)\n","><");
break;
case lss:
printf("( lss,%-10s)\n","<");
break;
case leq:
printf("( leq,%-10s)\n","<=");
break;
case gtr:
printf("( gtr,%-10s)\n",">");
break;
case geq:
printf("( geq,%-10s)\n",">=");
break;
case lparen:
printf("( lparen,%-10s)\n","(");
break;
case rparen:
printf("( rparen,%-10s)\n",")");
break;
case semicolon:
printf("( semicolon,%-10s)\n",";");
break;
case comma:
printf("( comma,%-10s)\n",",");
break;
case becomes:
printf("( becomes,%-10s)\n",":=");
break;
case beginsym:
printf("( beginsym,%-10s)\n","begin");
break;
case endsym:
printf("( endsym,%-10s)\n","end");
break;
case ifsym:
printf("( ifsym,%-10s)\n","if");
break;
case thensym:
printf("( thensym,%-10s)\n","then");
break;
case whilesym:
printf("( whilesym,%-10s)\n","while");
break;
case dosym:
printf("( dosym,%-10s)\n","do");
break;
case elsesym:
printf("( elsesym,%-10s)\n","else");
break;
case intsym:
printf("( intsym,%-10s)\n","int");
break;
case doublesym:
printf("( doublesym,%-10s)\n","double");
break;
case floatsym:
printf("( floatsym,%-10s)\n","float");
break;
case longsym:
printf("( longsym,%-10s)\n","long");
break;
case ident:
printf("( ident,%-10s)\n",token);
break;
default:
break;
}
}
void getsym()
{
for(m=0; m<8;m++) token[m++]=NULL;
ch=line[p++];
m=0;
/************************************************
**** ****
**** TODO: 单词识别 ****
**** ****
*************************************************/
while((ch==' '||ch=='\n')) ch=line[p++];
//字母打头的字符串;标识符
if((ch<='z'&&ch>='a')||(ch<='Z'&&ch>='A'))
{
do
{
token[m++]=ch;
ch=line[p++];
}while((ch<='z'&&ch>='a')||(ch<='Z'&&ch>='A')||(ch<='9'&&ch>='0'));
sym=ident;
token[m++]='\0';
ch=line[p--];
for(int n=0;n<11;n++)
{
if(strcmp(token,word[n])==0)
{
if(n==0) sym=beginsym;
else if(n==1) sym=endsym;
else if(n==2) sym=ifsym;
else if(n==3) sym=thensym;
else if(n==4) sym=whilesym;
else if(n==5) sym=dosym;
else if(n==6) sym=elsesym;
else if(n==7) sym=intsym;
else if(n==8) sym=doublesym;
else if(n==9) sym=floatsym;
else if(n==10) sym=longsym;
break;
}
}
/*TODO识别标识符IDENT和保留字*/
}
else if((ch<='9'&&ch>='0'))
{
num=0;
do{
num=num*10+ch-'0';
ch=line[p++];
}while((ch<='9'&&ch>='0'));
ch=line[p--];
sym=number;
/*TODO识别数字NUMBER*/
}
else {
switch(ch)
{
case ':': //赋值符号
token[m++]=ch;
ch=line[p++];
if(ch=='=')
{
sym=becomes;
token[m++]=ch;
}
else{
sym=nil;
}
break;
case '<': //<=和<符号
token[m++]=ch;
ch=line[p++];
if(ch=='=')
{
token[m++]=ch;
sym=leq;
}
else if(ch=='>'){
token[m++]=ch;
sym=neq;
}
else{
sym=lss;
p--;
}
break;
case '>': //>=和>符号
token[m++]=ch;
ch=line[p++];
if(ch=='=')
{
sym=geq;
token[m++]=ch;
}
else{
sym=gtr;
p--;
}
break;
case '+':
sym=Plus;
token[m++]=ch;
break;
case '-':
sym=Minus;
token[m++]=ch;
break;
case '*':
sym=times;
token[m++]=ch;
break;
case '/':
ch=line[p++];
if(ch=='*'){
//cout<<"in\n";
char fr;//前面的一个符号
fr='*';
ch=line[p++];
while(1){
fr=ch;
ch=line[p++];
if(fr=='*'&&ch=='/') break;
}
sym=note;
token[m++]=ch;
}
else
{
sym=slash;
token[m++]=ch;
p--;
}
break;
case '=':
sym=eql;
token[m++]==ch;
break;
case '(':
sym=lparen;
token[m++]=ch;
break;
case ')':
sym=rparen;
token[m++]=ch;
break;
case ';':
sym=semicolon;
token[m++]=ch;
break;
case ',':
sym=comma;
token[m++]=ch;
break;
case '.':
sym=period;
token[m++]=ch;
break;
case ' ':
token[m++]=ch;
break;
default:
sym=nil;
break;
}
}
token[m++]='\0';
//如果想看分析的每一个sym,请打开这个注释
printSym(sym);
//处理语句分析中的注释
if(sym==note) getsym();
}
void error(int i)
{
switch (i)
{
case 1:
printf("Error %d: 没有检测到语句期望begin符号\n", i);
break;
case 2:
printf("Error %d: 没有检测到赋值语句的 := 符号\n",i);
break;
case 3:
printf("Error %d: 没有检测到条件语句的 then 符号\n",i);
break;
case 4:
printf("Error %d: 没有检测到循环语句的 do 符号\n",i);
break;
case 5:
printf("Error %d: 错误的句子!\n",i);
break;
case 6:
printf("Error %d: 你写了数字!\n",i);
break;
case 7:
printf("Error %d: 没有检测到 '(' 的 ')' 符号\n",i);
break;
case 8:
printf("Error %d: 没有检测到因子\n",i);
break;
case 9:
printf("Error %d: 没有检测到关系运算符\n",i);
break;
case 10:
printf("Error %d: 没有检测到标识符\n",i);
break;
case 11:
printf("Error %d: 没有检测到语句期望 end 符号\n", i);
break;
case 12:
printf("Error %d: 没有检测到定义结束标记 ; 符号\n", i);
break;
case 13:
printf("Error %d: %d 处的 %s 没有定义\n", i,p,token);
break;
default:
break;
}
flag=false;
Err++;
}
int block()
{
cout<<"程序块分析\n";
if (sym != beginsym)
{
error(1);
}
else
{
getsym();
statement(); //语句处理
while (sym == semicolon)
{
getsym();
statement(); //语句处理
}
if (sym != endsym&&flag)
{
error(11);
}
getsym();
}
return 0;
}
void statement()
{
/********************************************
**** TODO: 语句处理(赋值/条件/循环) *****
*******************************************/
cout<<"语句处理\n";
if(sym==ident)
{
//赋值语句
cout<<"赋值语句分析\n";
getsym();
if(sym==becomes)
{
getsym();
expression();
//printf(" print( %s ) ",token);
}
else
{
error(2);
//printf("Error!赋值语句左部标识符后面应是赋值号 ':='\n");
return;
}
}
else if(sym==ifsym)
{
//条件语句
cout<<"条件语句分析\n";
getsym();
condition();
if(sym==thensym)
{
getsym();
statement();
if(sym==elsesym){
cout<<"else语句分析\n";
getsym();
statement();
}
else if(sym==endsym){
return;
}
else{
statement();
}
}
else
{
error(3);
//printf("Error!条件语句条件后面应是 'then'\n");
return;
}
}
else if(sym==whilesym)
{
//循环语句
cout<<"循环语句分析\n";
getsym();
condition();
if(sym==dosym)
{
getsym();
statement();
}
else
{
error(4);
//printf("Error!循环语句条件后面应是 'do'\n");
return;
}
}
else if(sym==intsym||sym==doublesym||sym==floatsym||sym==longsym){
//变量定义语句
cout<<"变量定义语句分析\n";
getsym();
is_ident();
getsym();
while(sym==comma){
getsym();
is_ident();
}
if(sym!=semicolon){
error(12);
return;
}
}
else
{
error(5);
//printf("错误的句子!\n");
return;
}
if(sym==number)
{
error(6);
//printf("你写了数字!\n");
return;
}
}
void expression()
{
cout<<"表达式处理\n";
/********************************************
*************** TODO: 表达式处理 *************
*******************************************/
if(sym==Plus||sym==Minus)
{
getsym();
term();
}
else
{
term();
while(sym==Plus||sym==Minus)
{
getsym();
term();
}
}
}
void term()
{
cout<<"项处理\n";
/********************************************
*************** TODO: 项处理 *************
*******************************************/
if(sym==times||sym==slash)
{
getsym();
factor();
}
else
{
factor();
while(sym==times||sym==slash)
{
getsym();
factor();
}
}
}
void factor()
{
cout<<"因子处理\n";
/********************************************
*************** TODO: 因子处理 *************
*******************************************/
if(sym==ident)
{
string s(&token[0],&token[strlen(token)]);
vector<string>::iterator result=find(define.begin(),define.end(),s);
if ( result == define.end()){
error(13);
}
else getsym();
}
else if(sym==number){
getsym();
}
else if(sym==lparen)
{
getsym();
expression();
if(sym==rparen) getsym();
else
{
error(7);
//printf("语法分析出错!请检查是否缺少 ')'\n");
return;
}
}
else
{
error(8);
//printf("Error!缺少因子\n");
return;
}
}
void condition()
{
cout<<"条件处理\n";
/********************************************
*************** TODO: 条件处理 *************
*******************************************/
expression();
//getsym();
Relational_operator();
getsym();
expression();
}
void Relational_operator()
{
cout<<"关系运算符处理\n";
/********************************************
*************** TODO: 关系运算符 *************
*******************************************/
if(sym==neq||sym==eql||sym==lss||sym==leq||sym==gtr||sym==geq||sym==8||sym==9||sym==10||sym==11||sym==12||sym==13)
{
//getsym();
}
else
{
error(9);
//printf("Error!缺少关系运算符\n");
return;
}
}
void is_ident()
{
cout<<"标识符处理\n";
/********************************************
*************** TODO: 关系运算符 *************
*******************************************/
if(sym==ident)
{
//getsym();
define.push_back(token);
}
else
{
error(10);
//printf("Error!缺少关系运算符\n");
return;
}
}