#include <iostream>
using namespace std;
#include <string.h>
char str[1000];
int num, k = 0, f = 0, now, ago; //f记录:=的个数,k记录;的个数,出现关键字begin和多字节id时借用now移动指针
int T = 0, Go = 1, L = 0, R = 0, Z = 1; //T来判断检索方向 T=0正向检索,T=1反向检索 Go 出现报错后终止程序
void Check_begin_end(); //判断是否包含begin end
void Check_assignment(); //检查赋值符号前后字符
void Check_id(int i); //检查id后面的字符
void Check_Leftparenthesis(int i); //检查( 后的字符
void Check_Operation(int i); //检查运算符后的字符
void Check_Rightparenthesis(int i); //检查右括号后的字符
int scaner(int i); //检索字符数组str的值
int scaner(int i)
{
char t[6], Gjz[2][10] = {"begin", "end"};
int j, j1;
switch (str[i])
{
case 'b':
for (j = 0, j1 = i; j <= 4; j++, j1++)
t[j] = str[j1];
if (strcmp(t, Gjz[0]) == 0)
{
now = j1; //指向begin的后一个字符上
return 1;
}
else
goto loop;
break;
case 'e':
for (j = 0, j1 = i; j <= 2; j++, j1++)
t[j] = str[j1];
t[j] = '\0';
if (strcmp(t, Gjz[1]) == 0)
return 6;
else
goto loop;
case '+':
return 13;
case '-':
return 14;
case '*':
return 15;
case '/':
return 16;
case ':':
if (str[i + 1] == '=')
return 18;
case '(':
return 27;
case ')':
return 28;
case '#':
return 0;
case ';':
return 26;
}
loop:
if (((str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z') || (str[i] >= '0' && str[i] <= '9')) && T == 1)
{
while ((str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z') || (str[i] >= '0' && str[i] <= '9'))
i--;
return 10;
}
else if (((str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z')) && T == 0)
{
while ((str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z') || (str[i] >= '0' && str[i] <= '9'))
i++;
now = i; //指向id后一个字符;
return 10;
}
else if (str[i] >= '0' && str[i] <= '9')
{
while (str[i] >= '0' && str[i] <= '9') //和上一步判断id10一样,让while浪费一步,保证指针的正常移动
i++;
now = i;
return 11;
}
else
return 155; //避免在出现不是以上字符时返回任意值;
}
void Check_Rightparenthesis(int i) //此时i指向 ) 后的第一个字符
{
R++;
int r;
r = scaner(i);
switch (r)
{
case 13:
case 14:
case 15:
case 16:
Check_Operation(i + 1); // )后出现运算符
break;
case 28: // )后出现 )
Check_Rightparenthesis(i + 1);
break;
case 26: // )后出现;
k++;
break;
case 6: // )后出现end
if (k == f - 1 && L == R)
cout << "sucess" << endl;
else if (k == f - 1 && L != R)
cout << "error(括号不匹配)" << endl;
else
cout << "error(缺少:=或;)" << endl;
Go = 0;
break;
default:
cout << "error( )后出现非法字符)" << endl;
Go = 0;
}
}
void Check_Operation(int i) //此时i指向运算符后的第一个字符
{
int r;
r = scaner(i);
switch (r)
{
case 10:
case 11:
Check_id(now);
break;
case 27:
Check_Leftparenthesis(i + 1);
break;
default:
Go = 0;
cout << "error(运算符后出现非法字符)" << endl;
}
}
void Check_id(int i) //此时i在id后面的第一个字符上
{
int r;
r = scaner(i);
switch (r)
{
case 13:
case 14:
case 15:
case 16:
Check_Operation(i + 1);
break; //id后面出现运算符
case 28: //id后面出现 )
Check_Rightparenthesis(i + 1);
break;
case 26: //id后面出现 ;
k++;
break;
case 6:
case 0: //id后面出现end,由于end在检索时会被并到id中,但是遇到#时一定能遇到end
if (k == f - 1 && L == R)
cout << "sucess" << endl;
else if (k == f - 1 && L != R)
cout << "error(括号不匹配)" << endl;
else if (k != f - 1 && L == R)
{
cout << "error(缺少;或者缺少:=)" << endl;
Go = 0;
}
break;
default:
cout << "error(id后出现非法字符)" << endl;
Go = 0;
}
}
void Check_Leftparenthesis(int i) //此时i是在 ( 后的第一个字符上
{
L++;
int r;
r = scaner(i);
switch (r)
{
case 10:
case 11:
Check_id(now);
break;
case 27:
Check_Leftparenthesis(i + 1);
break;
default:
cout << "error(左括号后出现非法字符)" << endl;
Go = 0;
}
}
void Check_assignment()
{
int i = now, r, j, j1; //now此时是在begin后一个的字符上
char o[6], p[6] = {"nigeb"};
r = scaner(i);
while (r != 6 && Go == 1)
{
if (r == 18) //出现赋值号 此时i指向的是赋值号中的 :
{
f++; //记录赋值符号的个数
T = 1;
r = scaner(i - 1); //检查赋值符号前面的字符
T = 0;
if (r != 10)
{
cout << "error( No." << f << ":= without id)" << endl; //赋值号前面不是 id 报错
Go = 0;
}
else
{
if (f == 1)
{
for (j = i - 1, j1 = 0; j1 <= 4; j--, j1++)
o[j1] = str[j];
o[j1] = '\0';
if (strcmp(o, p) == 0 && (str[0] == o[j1 - 1]))
{
cout << "error( No." << f << ":= without id)" << endl; //赋值号前面是 begin 报错
Go = 0;
}
else
{
r = scaner(i + 2); //i在这时候指向的是:需要往后加2才能指到赋值号后的东西
if (r == 27) // 赋值号后面出现 (
Check_Leftparenthesis(i + 3);
else if (r == 10 || r == 11) // 赋值号后面出现 id
Check_id(now);
else
{
cout << "error(No." << f << " :=后出现非法字符 )" << endl;
Go = 0;
}
}
}
else
{
r = scaner(i + 2); //i在这时候指向的是:需要往后加2才能指到赋值号后的东西
if (r == 27) // 赋值号后面出现 (
Check_Leftparenthesis(i + 3);
else if (r == 10 || r == 11) // 赋值号后面出现 id
Check_id(now);
else
{
cout << "error(No." << f << " :=后出现非法字符 )" << endl;
Go = 0;
}
}
}
}
i++;
r = scaner(i);
}
if (f == 0 || k != f - 1)
cout << "error(缺少:=或者缺少;)" << endl; //缺少:=或者:=与;在数量上不匹配;
}
void Check_begin_end() //判断第一个字符是不是关键字begin,以及end,#
{
int i = 0, r = 0;
r = scaner(i);
if (r != 1)
cout << "error(without begin)" << endl;
else
{
i = num;
r = scaner(i - 3);
if (r != 6)
cout << "error(without end)" << endl;
else
Check_assignment();
}
}
int main()
{
loop1:
int i = 0, C;
k = f = L = R = 0;
Go = 1;
cout << "__________________________________" << endl;
cout << "__________________________________" << endl;
cout << "Input end with #" << endl;
cin >> str[i];
while (str[i] != '#')
{
i++;
cin >> str[i];
}
num = i;
Check_begin_end();
cout << "If continue,input 1: ";
cin >> C;
cout << endl;
if (C == 1)
goto loop1;
else
return 0;
}