69,373
社区成员
发帖
与我相关
我的任务
分享
/********************************************
*文法规则集合
*E := '(' E ')' | E1
*E1:= E2 ( + E2 | - E2 |e)
*E2:= E3 ( * E3 | / E3 |e)
*E3:= '(' ( E ) ')'| NUM
*NUM := number
*为简单起见,仅仅支持正数
*********************************************/
#include <stdio.h>
#include <stdlib.h>
#define MAX 999999
#define DEBUG
struct node
{
char symbol;
int number;
node *next;
}root;
char comstr[100] = {0};
node *nextnode = NULL;
node *nextword = &root;
int E();
int E1();
int E2();
int E3();
void debug()
{
node *a = &root;
while(true)
{
if(a->next != NULL)
{
printf(" : %c\n", a->symbol);
a = a->next;
}
else break;
}
}
bool getnextword()
{
if(nextword->next!=NULL)
{
if(nextword->next->next != NULL)
{
nextword = nextword->next;
return true;
}
}
else
{
printf("End of input\n");
return false;
}
}
void deleteall(node * next)//删除链表释放内存
{
if(next->next!=NULL)
{
deleteall(next->next);
}
else
{
delete next;
}
}
/****************************
据文法规则产生函数E系列
****************************/
int E()
{
#ifdef DEBUG
printf("E\n");
#endif
int res = 0;
if(nextword->symbol == '(')
{
if(!getnextword())
{
exit(0);
}
res = E();
if(nextword->symbol == ')')
{
getnextword();
}
else
{
printf("syntax error! missing ')'\n");
exit(0);
}
}
else
{
res = E1();
}
return res;
}
int E1()
{
#ifdef DEBUG
printf("E1\n");
#endif
int res1 = 0, res2 = 0;
res1 = E2();
if(nextword->symbol == '+')
{
if(!getnextword())
{
exit(0);
}
res2 = E2();
return res1 + res2;
}
else if(nextword->symbol == '-')
{
if(!getnextword())
{
exit(0);
}
res2 = E2();
return res1 - res2;
}
else
{
return res1;
}
}
int E2()
{
#ifdef DEBUG
printf("E2\n");
#endif
int res1 = 0, res2 = 0;
res1 = E3();
if(nextword->symbol == '*')
{
if(!getnextword())
{
exit(0);
}
res2 = E3();
return res1 * res2;
}
else if(nextword->symbol == '/')
{
if(!getnextword())
{
exit(0);
}
res2 = E3();
if(res2 == 0)
{
printf("Error! devide 0 !\n");
exit(0);
}
return res1 / res2;
}
else
{
return res1;
}
}
int E3()
{
#ifdef DEBUG
printf("E3\n");
#endif
int res = 0;
if(nextword->symbol == '(')
{
if(!getnextword())
{
exit(0);
}
res = E();
if(nextword->symbol == ')')
{
getnextword();
return res;
}
else
{
printf("syntax error! missing ')'\n");
exit(0);
}
}
else if(nextword->symbol == 'n')
{
res = nextword->number;
getnextword();
return res;
}
}
/****************************
check用于产生单词链表
****************************/
int check(char * str, int len)
{
root.next = NULL;
nextnode = &root;
node *newnode = NULL;
int num = 0;
bool last_is_num = true;
for(int index = 0; index < len; ++index)
{
if(str[index] >= '0' && str[index] <= '9')
{
if(last_is_num)
{
num = 10 * num + str[index] - '0';
if(num > MAX)
{
printf("Too big number! %d\n", num);
return 0;
}
}
else
{
last_is_num = true;
num = str[index] - '0';
}
if(index == len -1)
{
newnode = new node;
nextnode->number = num;
nextnode->symbol = 'n';//数字标志
nextnode->next = newnode;
nextnode = newnode;
nextnode->next = NULL;
}
}
else
{
if(last_is_num)//检查到上次循环得到了数字
{
newnode = new node;
nextnode->number = num;
nextnode->symbol = 'n';//数字标志
num = 0;
last_is_num = false;
nextnode->next = newnode;
nextnode = newnode;
nextnode->next = NULL;
}
newnode = new node;
nextnode->symbol = str[index];
nextnode->next = newnode;
nextnode = newnode;
nextnode->next = NULL;
}
}
return 1;
}
int main()
{
printf("Please input the sentense ,end with'='(No more than 100 bytes):\n");
char input = 0;
int len = 0;
while(scanf_s("%c", &input))
{
if(input == '=')
{
break;
}
else if(input >= '0' && input <= '9' || input == '+' || input == '-' || input == '*' || input == '/' || input == '(' || input == ')')
{
comstr[len] = input;
++len;
if(len > 98)
{
printf("Too long sentense!\n");
return 0;
}
}
else if(input == 0x09 || input == ' ' || input == 0x0d || input == 0x0a)
{
}
else
{
printf("Invalid input: %d\n", input);
return 0;
}
}
if(len == 0)
{
printf("No input\n");
return 0;
}
else
{
comstr[len] = '\0';
//printf("%s", comstr);
}
if(check(comstr, len) == 0)
{
printf("Invalid sentense\n");
exit(0);
}
else
{
printf("result: %s = %d\n",comstr, E());
#ifdef DEBUG
debug();
printf("len is %d\n", len);
#endif
if(root.next != NULL)
{
deleteall(root.next);
}
}
}