您的位置:首页 > 编程语言 > C语言/C++

语法分析程序

2016-06-05 17:10 363 查看
工程代码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;
}



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c语言 编译原理