语法分析程序

时间:2021-10-28 17:06:25

工程代码http://download.csdn.net/detail/fulianzhou/9541833

config.h

/*****  *********/
#ifndef _CONFIG_H_
#define _CONFIG_H_

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

//#define LEX_OUTPUT

#define MAXSTRLEN 1024
#define UNDEFINE_DATA -1

// 单词类型
const enum TYPE{
em_start = 1,// #
em_add, // +
em_sub, // -
em_mul, // *
em_div, // /
em_equ, // =

em_left, // (
em_right, // )

em_int, // int
em_real, // real

em_mark, // mark

em_sem, // ;
em_com, // ,

em_default, // 无法识别
};

// 元素数据
typedef struct {
TYPE type;
char *name;
union{
int int_dat;
double real_dat;
}value;
}ElemType;

// 优先关系表
const char g_cPriorList[10][10]={
/* + - * / = ( ) i V # */
/* + */ '>', '>', '<', '<', ' ', '<', '>', '<', '<', ' ', // 0
/* - */ '>', '>', '<', '<', ' ', '<', '>', '<', '<', ' ', // 1
/* * */ '>', '>', '>', '>', ' ', '<', '>', '<', '<', ' ', // 2
/* / */ '>', '>', '>', '>', ' ', '<', '>', '<', '<', ' ', // 3
/* = */ '<', '<', '<', '<', ' ', '<', '>', '<', '<', ' ', // 4
/* ( */ '<', '<', '<', '<', ' ', '<', '=', '<', '<', ' ', // 5
/* ) */ '>', '>', '>', '>', ' ', ' ', '>', ' ', ' ', '>', // 6
/* i */ '>', '>', '>', '>', ' ', ' ', '>', ' ', ' ', '>', // 7
/* V */ '>', '>', '>', '>', '=', ' ', '>', ' ', ' ', '>', // 8
/* # */ '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '<', '=', // 9
};

// 查询优先关系表,得优先关系
char GetPrior(TYPE left,TYPE right);
// 形成数据
ElemType FormElemData(char *name,TYPE type,double data);
// 显示元素内容
void DispElem(ElemType item);

#endif

config.cpp

#include "config.h"

// 形成数据结点
ElemType FormElemData(char *name,TYPE type,double data){
ElemType item;
item.name = (char*)calloc(sizeof(char),strlen(name)+1);
strcpy(item.name,name);
item.type = type;
if(item.type == em_int) item.value.int_dat = (int)data;
else if(item.type == em_real) item.value.real_dat = data;
else item.value.real_dat = data;

return item;
}

// 显示元素内容
void DispElem(ElemType item){
printf("(%s,%d,%g)\n",item.name,item.type,item.type == em_int ? item.value.int_dat : item.value.real_dat);
}

// 根据有限关系表获取坐标值
static int GetPos(TYPE type){
switch(type){
case em_add:return 0;
case em_sub:return 1;
case em_mul:return 2;
case em_div:return 3;
case em_equ:return 4;
case em_left:return 5;
case em_right:return 6;
case em_int:
case em_real:return 7;
case em_mark:return 8;
case em_start:return 9;
}
return -1;
}

// 查询优先关系表,得优先关系
char GetPrior(TYPE left,TYPE right){
int iLeft = GetPos(left);
int iRight = GetPos(right);
if(iLeft >= 0 && iRight >= 0){
return g_cPriorList[iLeft][iRight];
}
else{
printf("Error, can not recognition type.\n");
return '-';
}
}

grammar_analysis.h

#ifndef _GRAMMAR_ANALYSIS_H_
#define _GRAMMAR_ANALYSIS_H_

#include "config.h"
#include "linklist.h"
#include "linkstack.h"


// 语法分析
int Grammar_Analysis(PT_List list);

#endif

grammar_analysis.cpp
#include "grammar_analysis.h"static int Grammar_CheckFormat(PT_List list){	int i;	TYPE t1,t2;	int l = LinkList_GetLength(list);	TYPE t = LinkList_GetNode(list,1)->data.type;	if(!(t == em_int || t==em_real || t==em_left)) return 0;		for(i=1;i < l;i++){		if(LinkList_GetNode(list,i)->data.type == em_mark) return 0;		if(LinkList_GetNode(list,i)->data.type == em_default) return 0;		if(LinkList_GetNode(list,i)->data.type == em_equ) return 0;		if(i>1 && i < l){			t1 = LinkList_GetNode(list,i-1)->data.type;			t2 = LinkList_GetNode(list,i)->data.type;				if((t1 == em_left && t2 == em_right) || (t1 == em_right && t2 == em_left))  // (),)(				return 0;			if((t1 == em_add || t1 == em_sub || t1 == em_mul || t1 == em_div) && 			   (t2 == em_add || t2 == em_sub || t2 == em_mul || t2 == em_div)) // ++,+-,+/...			   return 0;			if(t1 == em_int || t1 == em_real){				if(t2 == em_add || t2 == em_sub || t2 == em_mul || t2 == em_div || t2 == em_right)				{}				else // 2 2,2(,					return 0;			}			if(t1 == em_add || t1 == em_sub || t1 == em_mul || t1 == em_div){				if(t2 == em_int || t2 == em_real || t2 == em_left){				}				else // +),++,...					return 0;			}		}	}	return 1;}// 计算Data EvaluateExpression(PT_List ptlist,int *flag){	int iIndex = 3;	int len = LinkList_GetLength(ptlist);	//printf("len = %d\n",len);	*flag = 1;     // 先置为合格	ElemType tmpData;	LinkList OPTR,OPND;	ListInit(OPTR);            //寄存运算符	ListInit(OPND);            // 寄存数字	Push_sign(OPTR,em_start);	/* 获取下一个 */	if(iIndex < len){ /*  */ 		tmpData = LinkList_GetNode(ptlist,iIndex)->data;		//printf("GetNode: iIndex:%d,name:%s\n",iIndex,tmpData.name);		iIndex++;	}	else{		tmpData.type = em_start;	}	if(tmpData.type == em_int || tmpData.type == em_real){		Push_num(OPND,tmpData.type == em_int ? atoi(tmpData.name):atof(tmpData.name));//Push_num(OPND,tmpData.value.real_dat);		/* 获取下一个 */		if(iIndex < len){ /*  */ 			tmpData = LinkList_GetNode(ptlist,iIndex)->data;			//printf("GetNode: iIndex:%d,name:%s\n",iIndex,tmpData.name);			iIndex++;		}		else{			tmpData.type = em_start;		}	}	while(tmpData.type != em_start || Get_top_sign(OPTR) != em_start)	{		if(tmpData.type == em_int || tmpData.type == em_real){			Push_num(OPND,tmpData.type == em_int ? atoi(tmpData.name):atof(tmpData.name));			/* 获取下一个 */			if(iIndex < len){ /*  */ 				tmpData = LinkList_GetNode(ptlist,iIndex)->data;				//printf("GetNode: iIndex:%d,name:%s\n",iIndex,tmpData.name);				iIndex++;			}			else{				tmpData.type = em_start;			}		}		switch(/*GetPrior*/Precede(Get_top_sign(OPTR),tmpData.type))		{		case '<':			Push_sign(OPTR,tmpData.type);			/* 获取下一个 */			if(iIndex < len){ /*  */ 				tmpData = LinkList_GetNode(ptlist,iIndex)->data;				//printf("GetNode: iIndex:%d,name:%s\n",iIndex,tmpData.name);				iIndex++;			}			else{				tmpData.type = em_start;			}			break;		case '=':			Pop_sign(OPTR);			/* 获取下一个 */			if(iIndex < len){ /*  */ 				tmpData = LinkList_GetNode(ptlist,iIndex)->data;				//printf("GetNode: iIndex:%d,name:%s\n",iIndex,tmpData.name);				iIndex++;			}			else{				tmpData.type = em_start;			}			break;		case '>':{			double s = Operate(Pop_num(OPND),Pop_sign(OPTR),Pop_num(OPND));			//printf("s = %g\n",s);			Push_num(OPND,s);			break;				 }		case '-':		case ' ': // 出现不合法的语法单元,退出			*flag = 0;			break;		}		if(*flag == 0) {			//printf("flag = 0,break;\n");			break;		}	}	//printf("Out!tmpdata.type = %d,top sign=%d\n",tmpData.type,Get_top_sign(OPTR));	return Pop_num(OPND);}// 语法分析int Grammar_Analysis(PT_List list){	PT_List  ptlist = list;	if(!(LinkList_GetNode(ptlist,1)->data.type == em_mark && LinkList_GetNode(ptlist,2)->data.type == em_equ)){		LinkList_DispAllRaw(list);		printf("\t --> can not calculate.\n");		return 0;	}	else	{		ptlist=ptlist->next;		ptlist=ptlist->next;		if(Grammar_CheckFormat(ptlist) == 0) {			LinkList_DispAllRaw(list);			printf("\t --> can not calculate.\n");			return 0;		}		}			int flag = 1;	double sum = EvaluateExpression(list,&flag);	LinkList_DispAllRaw(list);	if(flag){		printf("\t --> %s%s%g;\n",LinkList_GetNode(list,1)->data.name,LinkList_GetNode(list,2)->data.name,sum);	}	else puts("\t --> can not calculate.\n");	return 0;}

lexical_analysis.h 

#ifndef _LEXICAL_ANALYSIS_
#define _LEXICAL_ANALYSIS_

#include "config.h"
#include "linklist.h"

// 词法分析
PT_List ParseWord(char strInput[]);
#endif

Lexical_analysis.cpp

/*
输入串必须以'#'号结尾
*/

#include "lexical_analysis.h"
#include "linklist.h"

/* 类别标志 */
TYPE g_type = em_default;

void OutputStr(char str[],int flag){
switch(flag){
case em_int:fprintf(stdout,"(%s,%d)\t整数\n",str,flag);break;
case em_real:fprintf(stdout,"(%s,%d)\t实数\n",str,flag);break;
case em_default:fprintf(stdout,"(%s,%d)\t无法识别\n",str,flag);break;
case em_mark:fprintf(stdout,"(%s,%d)\t标识符\n",str,flag);break;
}
}

// 解析单词
PT_List ParseWord(char strInput[]){
int i,j;
char strTemp[MAXSTRLEN] = { 0 }; // 临时数组,用于保存单词
int iLen = 0; // 临时数组长度
int iDot; // 小数点出现标识符
PT_List ptlist = (PT_List)calloc(sizeof(T_List),1);
LinkList_Init(ptlist);

g_type = em_default; // 标志为未处理

for(i=0;strInput[i] && strInput[i] != '#';i++){
if(isdigit(strInput[i])){ // 如果是数字
iDot = 0; // 小数点没有出现过
memset(strTemp,0,sizeof(strTemp)); // 清空临时数组
iLen = 0; // 临时数组长度为0
g_type = em_int; // 标志为整数

for(j=i;strInput[i] && strInput[j] != '#';j++){
if(strInput[j] == '.'){ // 如果出现小数点x
if(iDot == 0){ // 如果小数点没有出现过
iDot = 1; // 标识为小数点已经出现
strTemp[iLen++] = strInput[j]; // 存在临时数组中
g_type = em_default; // 标志为无法识别
}
else{ // 第二次出现小数点出错
j--;
break;
}
}
else if(isdigit(strInput[j])){ // 如果是数字
strTemp[iLen++] = strInput[j];
if(g_type == em_default)
g_type = em_real;
}
else{
j--;
break;
}
}
#ifdef LEX_OUTPUT
OutputStr(strTemp,g_type);
#endif
if(g_type == em_default){
LinkList_AddNode(ptlist,FormElemData(strTemp,g_type,UNDEFINE_DATA));
}
else{
LinkList_AddNode(ptlist,FormElemData(strTemp,g_type,g_type == em_int ? atoi(strTemp) : atof(strTemp)));
}
memset(strTemp,0,sizeof(strTemp)); // 清空临时数组
iLen = 0; // 临时数组长度为0
i = j;
}
else if(isalpha(strInput[i])){ // 如果是以字母开头
memset(strTemp,0,sizeof(strTemp));
iLen = 0;
g_type = em_mark; // 标记为标识符
for(j=i;strInput[i] && strInput[j] != '#';j++){
if(isalpha(strInput[j]) || isdigit(strInput[j])){ // 如果是数字或者字母
strTemp[iLen++] = strInput[j];
}
else{
j--;// 否则
break;
}
}
#ifdef LEX_OUTPUT
OutputStr(strTemp,g_type);
#endif
LinkList_AddNode(ptlist,FormElemData(strTemp,g_type,UNDEFINE_DATA));
iLen = 0;
memset(strTemp,0,sizeof(strTemp));
i = j;
}
else if(isspace(strInput[i])) continue;
else{
switch(strInput[i]){
case '+':g_type = em_add;break;
case '-':g_type = em_sub;break;
case '*':g_type = em_mul;break;
case '/':g_type = em_div;break;
case '=':g_type = em_equ;break;
case ';':g_type = em_sem;break;
case ',':g_type = em_com;break;
case '(':g_type = em_left;break;
case ')':g_type = em_right;break;
default:g_type = em_default;
}
strTemp[0] = strInput[i];
strTemp[1] = '\0';
LinkList_AddNode(ptlist,FormElemData(strTemp,g_type,UNDEFINE_DATA));
#ifdef LEX_OUTPUT
fprintf(stdout,"(%c,%d)",strInput[i],g_type);
if(g_type == em_add || g_type == em_sub || g_type == em_mul || g_type == em_div || g_type == em_equ)
printf("\t运算符\n");
else if(g_type == em_sem || g_type == em_com)
printf("\t界符\n");
else
printf("\t无法识别\n");
#endif
}
}
return ptlist;
}

linklist.h

#ifndef _LINKLIST_H_
#define _LINKLIST_H_
#include "config.h"

typedef struct tLNode{
tLNode *next;
ElemType data;
}T_List,*PT_List;

// 添加结点
int LinkList_AddNode(PT_List ptlist,ElemType item);
// 初始化链表
void LinkList_Init(PT_List ptlist);
// 添加结点
int LinkList_AddNode(PT_List ptlist,ElemType item);
// 显示所有节点
void LinkList_DispAll(PT_List ptlist);
// 获取链表长度
int LinkList_GetLength(PT_List ptlist);
// 获取指定位置结点
PT_List LinkList_GetNode(PT_List ptlist,int pos);
// 显示所有节点名字
void LinkList_DispAllRaw(PT_List ptlist);
// 销毁链表
void LinkList_Destroy(PT_List ptlist);
#endif

Linklist.cpp

#include "linklist.h"


// 初始化链表
void LinkList_Init(PT_List ptlist){
ptlist->data = FormElemData("<head>",em_default,UNDEFINE_DATA);
ptlist->next = NULL;
}

// 添加结点
int LinkList_AddNode(PT_List ptlist,ElemType item){
PT_List tmplist = ptlist;
while(tmplist->next != NULL){
tmplist = tmplist->next;
}
PT_List newNode = (PT_List)calloc(sizeof(T_List),1);
newNode->next = NULL;
newNode->data = item;

tmplist->next = newNode;
return 1;
}

// 显示所有节点
void LinkList_DispAll(PT_List ptlist){
PT_List tmplist = ptlist;
while(tmplist->next != NULL){
tmplist = tmplist->next;
DispElem(tmplist->data);
}
}
// 显示所有节点名字
void LinkList_DispAllRaw(PT_List ptlist){
PT_List tmplist = ptlist;
while(tmplist->next != NULL){
tmplist = tmplist->next;
//DispElem(tmplist->data);
printf("%s",tmplist->data.name);
}
}
// 获取链表长度
int LinkList_GetLength(PT_List ptlist){
int len = 0;
PT_List tmplist = ptlist;
while(tmplist->next != NULL){
tmplist = tmplist->next;
len++;
}
return len;
}

// 获取指定位置结点
PT_List LinkList_GetNode(PT_List ptlist,int pos){
if(pos <= 0 || pos > LinkList_GetLength(ptlist)){
printf("Out of range.\n");
return NULL;
}
int num = 1;
PT_List tmpList = ptlist;
while(tmpList->next != NULL && num <= pos){
tmpList = tmpList->next;
num++;
}
return tmpList;
}

// 获取下一个
PT_List LinkList_GetNext(PT_List ptlist){
if(ptlist->next != NULL){
PT_List tmpList = ptlist;
ptlist = ptlist->next;
return tmpList;
}
return NULL;
}

// 销毁链表
void LinkList_Destroy(PT_List ptlist){
while(ptlist->next){
PT_List tmplist = ptlist;
ptlist = ptlist->next;
free(tmplist);
}
free(ptlist);
}

linkstack.h

#ifndef _LINKSTACK_H_
#define _LINKSTACK_H_

#define OK 1
#define NO 0
#define ERROR 0
#define OVERFLOW -1
typedef TYPE Sign;
typedef int Status;
typedef double Data;

typedef struct LNode
{
Sign sign;
Data num;
struct LNode *prior;
}LNode,*LinkList;

//初始化
Status ListInit(LinkList &L);
//数字入栈
Status Push_num(LinkList &L,Data e);
//字符入栈
Status Push_sign(LinkList &L,Sign e);
// 字符出栈
Sign Pop_sign(LinkList &L);
//数字出栈
Data Pop_num(LinkList &L);
// 判断栈空
Status Empty(LinkList L);
// 得栈顶字符元素
Sign Get_top_sign(LinkList L);
// 判断优先性
char Precede(TYPE c1,TYPE c2);
// 运算
double Operate(double x,TYPE c,double y);
#endif

linkstack.cpp

#include "config.h"
#include "linkstack.h"

Status ListInit(LinkList &L) ///初始化
{
L=(LinkList)malloc(sizeof(LNode));
L->prior=NULL;
return OK;
}

Status Push_num(LinkList &L,double e) ///数字入栈
{
LinkList p=(LinkList)malloc(sizeof(LNode));
p->num=e;
p->prior=L;
L=p;
//printf("Push_num:%.2f\n",e);
return OK;
}
Status Push_sign(LinkList &L,Sign e) /// 字符入栈
{
LinkList p=(LinkList)malloc(sizeof(LNode));
p->sign=e;
p->prior=L;
L=p;
//printf("Push_sign:%d\n",e);
return OK;
}
Sign Pop_sign(LinkList &L) /// 字符出栈
{
if(L->prior!=NULL)
{
LinkList p=L;
Sign x=L->sign;
L=L->prior;
free(p);
//printf("Pop_sign:%d\n",x);
return x;
}
}
Data Pop_num(LinkList &L) ///数字出栈
{
if(L->prior!=NULL)
{
LinkList p=L;
Data a=L->num;
L=L->prior;
free(p);
//printf("Pop_num:%g\n",a);
return a;
}
}
Status Empty(LinkList L) /// 判断栈空
{
if(L->prior==NULL) return 1;
return 0;
}
Sign Get_top_sign(LinkList L) /// 得栈顶字符元素
{
if(L->prior!=NULL)
return L->sign;
}
char Precede(TYPE c1,TYPE c2) /// 判断优先性
{
if((c1==em_add||c1== em_sub) && (c2==em_add||c2==em_sub||c2==em_right||c2==em_start))
return '>';
else if((c1==em_add||c1==em_sub) && (c2==em_mul||c2==em_div||c2==em_left))
return '<';

if((c1==em_mul||c1==em_div) && (c2==em_add||c2==em_sub||c2==em_mul||c2==em_div||c2==em_right||c2==em_start))
return '>';
else if((c1==em_mul||c1==em_div) && c2==em_left )
return '<';

if(c1==em_left && (c2==em_add||c2==em_sub||c2==em_mul||c2==em_div||c2==em_left))
return '<';
else if(c1==em_left && c2==em_right)
return '=';

if(c1==em_right)
return '>';

if(c1==em_start && c2==em_start)
return '=';
else
return '<';
}

// 运算
double Operate(double x,TYPE type,double y){
double s = 0;
switch(type){
case em_add:s = x + y;break;
case em_sub:s = x - y;break;
case em_mul:s = x * y;break;
case em_div:s = x / y;break;
}
return s;
}

main.cpp

#include "lexical_analysis.h"
#include "grammar_analysis.h"

int main(int argc,char *argv[]){
char strInput[MAXSTRLEN] = { 0 };
char c;
int iLen = 0;

printf("Input lines.\n\tevery sentence end by ';',end of '#':\n");

while(1){
memset(strInput,0,sizeof(strInput));
iLen = 0;
c = 0;
while((c = (char)getc(stdin)) != '#') strInput[iLen++] = c;
strInput[iLen] = '\0';
PT_List ptList = ParseWord(strInput);
int listlen = LinkList_GetLength(ptList);
//printf("length = %d\n",listlen);
puts("lexical analysis:");
LinkList_DispAll(ptList);

puts("");
puts("grammar analysis:");
int n = 1;
ElemType e;
while(n <= LinkList_GetLength(ptList)){
PT_List list = (PT_List)calloc(sizeof(T_List),1);
LinkList_Init(list);
while(n < listlen && (e = LinkList_GetNode(ptList,n)->data).type != em_sem){ // 找出一句
LinkList_AddNode(list,e);
n++;
}
LinkList_AddNode(list,LinkList_GetNode(ptList,n)->data);
n++;
/* 开始语法分析 */
Grammar_Analysis(list);
LinkList_Destroy(list);
}
printf("\ninput new lines:\n");
}
return 0;
}
语法分析程序

语法分析程序