语法分析程序
Posted fulianzhou
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了语法分析程序相关的知识,希望对你有一定的参考价值。
工程代码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;
}
以上是关于语法分析程序的主要内容,如果未能解决你的问题,请参考以下文章
在下面的代码片段中的剩余 ='passthrough' 处的代码中出现语法错误