📄 bianyi .txt
字号:
switch(type)
{
case INTEGER: get_exp((int*)result,index);
return 1;
default: return 0;
}
}
int CExecutable::Ai_GetVarNo(char *name,int *result,int type)
{
switch(type)
{
case INTEGER:
{
if(m_intArray.size()==0)
return 0;
for(int i=0;i<=m_intArray.size()-1;i++)
if(!strcmp(name,m_intArray.at(i).name))
*result=i;
return 1;
}
default: return 0;
}
}
void CExecutable::get_exp(int *result,int *index)
{
if (!*m_tokens.at(*index).token)
{
serror(2);
return;
}
level2(result,index);
}
/* add or subtract two terms */
void CExecutable::level2(int *result,int *index)
{
register char op;
int hold;
level3(result,index);
while ((op = *m_tokens.at(*index).token) =='+' || op == '-')
{
(*index)++;
level3(&hold,index);
arith(op,result,&hold);
}
}
/* multiply or divide two factors */
void CExecutable::level3(int *result,int *index)
{
register char op;
int hold;
level4(result,index);
while ((op = *m_tokens.at(*index).token) == '*' || op == '/' || op == '%')
{
(*index)++;
level3(&hold,index);
arith(op,result,&hold);
}
}
/* process integer exponent */
void CExecutable::level4(int *result,int *index)
{
register char op;
int hold;
level5(result,index);
if ((op = *m_tokens.at(*index).token) == '^')
{
(*index)++;
level5(&hold,index);
arith(op,result,&hold);
}
}
/* is a unary + or - */
void CExecutable::level5(int *result,int *index)
{
register char op;
op = 0;
if ((m_tokens.at(*index).token_type==DELIMITER) &&
*m_tokens.at(*index).token == '+' ||
*m_tokens.at(*index).token == '-' )
{
op = *m_tokens.at(*index).token;
(*index)++;
}
level6(result,index);
if (op)
if(op=='-')
*result=-(*result);
}
/* process parenthesized expression */
void CExecutable::level6(int *result,int *index)
{
if ((*m_tokens.at(*index).token == '(') && (m_tokens.at(*index).token_type == DELIMITER))
{
(*index)++;
level2(result,index);
if (*m_tokens.at(*index).token!=')')
serror(1);
(*index)++;
}
else
primitive(result,index);
}
/* find value of number or variable */
void CExecutable::primitive(int *result,int *index)
{
int token_type=m_tokens.at(*index).token_type;
if(Isvar(m_tokens.at(*index).token))
token_type=VARIABLE;
switch (token_type) {
case VARIABLE:
find_var(m_tokens.at(*index).token,result);
(*index)++;
return;
case NUMBER:
*result = atoi(m_tokens.at(*index).token);
(*index)++;
return;
default:
serror(0);
}
}
int CExecutable::find_var(char *var_name,void *value)
{
for(int i=0;i<=m_intArray.size()-1;i++)
if(!strcmp(var_name,m_intArray.at(i).name))
{
int *int_value=(int *)value;
*int_value=m_intArray.at(i).value;
return 1;
}
return 0;
}
int CExecutable::Isvar(char *name)
{
if(m_intArray.size()==0)
return 0;
for(int i=0;i<=m_intArray.size()-1;i++)
if(!strcmp(name,m_intArray.at(i).name))
return INTEGER;
return 0;
}
/* perform the specified arithmetic */
void CExecutable::arith(char o,int *r,int *h)
{
/*register*/ int t,ex;
switch (o) {
case '-':
*r = *r-*h;
break;
case '+':
*r = *r+*h;
break;
case '*':
*r = *r**h;
break;
case '/':
*r = (*r)/(*h);
break;
case '%':
*r = (*r)%(*h);
break;
case '^':
ex = *r;
if (*h==0) {
*r = 1;
break;
}
for (t=*h-1;t>0;--t) *r=(*r)*ex;
break;
}
}
int CExecutable::look_up(char *c)
{
if(strcmp(c,"print")==0)
return PRINT;
if(strcmp(c,"Integer")==0)
return INTEGER;
if(strcmp(c,"Dim")==0)
return DIM;
if(strcmp(c,"As")==0)
return AS;
return 0;
}
void CExecutable::serror(int error)
{
char *e[] = {
"syntax error",
"unbalanced parentheses",
"no expression present",
"equal sign expected",
"not a variable",
"label table full",
"duplicate label",
"undefined label",
"THEN expected",
"TO expected",
"too many nested FOR loops",
"NEXT without FOR",
"too many nested GOSUB",
"RETURN without GOSUB"
};
printf ("%s ",e[error]);
}
---------------------------
接着昨天的词法分析器,语法分析主要是将从词法分析那里得来的记号构成一棵语法树。这次我将作案的词法分析部分的代码稍作了修改,让他更适合语法分析器。我使用的是自下而上的分析法,针对算符优先文法的产生式构造语法树。
以下的代码只支持7种节点——加减乘除,标识符,数字,表达式。想要加入其他节点,在opprio数组中加入优先级。
////////////////////////////////Parse.h//////////////////////////////////
#ifndef _PARSE_H_
#define _PARSE_H_
#include "lexical.h"
//算法优先文法中优先级关系枚举
typedef enum {LS, GT, EQ,UN} Priority;
//移进归约算法中使用到的栈节点结构(双向链表)
typedef struct _pstacktoken
{
LexToken *ptoken;
struct _pstacktoken *pr;
struct _pstacktoken *nt;
struct _pstacktoken *child;
}PStackToken;
void PStackPush(LexToken *t);
LexToken* PStackPop();
//产生式链表节点结构(单向链表)
typedef struct _generator {LexTokenType *gen; int size; struct _generator *nt;} Generator;
PStackToken* Parse(char *Source);
#endif//_PARSE_H
////////////////////////////////////////Parse.c/////////////////////////////
#include "Parse.h"
#include <malloc.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
//各个运算符之间的优先级定义
#define OPNUM 7
Priority opprio[OPNUM][OPNUM]={
{GT,GT,LS,LS,LS,LS,GT,},
{GT,GT,LS,LS,LS,LS,GT,},
{GT,GT,GT,GT,LS,LS,GT,},
{GT,GT,GT,GT,LS,LS,GT,},
{GT,GT,GT,GT,UN,UN,GT,},
{GT,GT,GT,GT,UN,UN,GT,},
{LS,LS,LS,LS,LS,LS,EQ,},
};
Priority PrioCmp(LexTokenType first, LexTokenType second)//这段函数被优化代码替代
{
if (first>=OPNUM || second>=OPNUM)
return UN;
return opprio[first][second];
}
PStackToken *PSbot = NULL;//栈底指针
PStackToken *PStop = NULL;//栈顶指针
//int PSnum = 0;//栈元素个数
void PStackPush(LexToken *t)
{
static int size = sizeof(PStackToken);
PStackToken *p = (PStackToken*)malloc(size);//不检查合法性
p->ptoken = t;//不对t的合法性检查
if (!PSbot)//第一个节点
{
PSbot = PStop = p;
p->pr = p->nt = NULL;
}
else
{
PStop->nt = p;
p->pr = PStop;
p->nt = NULL;
PStop = p;
}
p->child = NULL;
}
LexToken* PStackPop()
{
LexToken *p = PStop->ptoken;
PStackToken *last = PStop;
if (PStop==NULL)//如果已无元素可弹出
return NULL;
PStop = PStop->pr;
PStop->nt = NULL;
free(last);
return p;
}
Generator *GLhead = NULL;
Generator *GLend = NULL;
void AddGen(int num, ...)
{
static int sizegen = sizeof(Generator);
static int sizetype = sizeof(LexTokenType);
Generator *pGen = (Generator*)malloc(sizegen);
int i;
va_list pArgList;
va_start (pArgList, num);
pGen->size = num;
pGen->gen = (LexTokenType*)malloc(sizetype);
pGen->nt = NULL;
for (i=0; i<num; i++)
{
pGen->gen[i] = va_arg(pArgList, LexTokenType);
}
va_end (pArgList);
if (!GLhead)
{
GLhead = pGen;
GLend = pGen;
}
else
{
GLend->nt = pGen;
GLend = pGen;
}
}
void InitGenerator()
{
AddGen(3,EXPRESSION,PLUS,EXPRESSION);
AddGen(3,EXPRESSION,MINUS,EXPRESSION);
AddGen(3,EXPRESSION,MULTI,EXPRESSION);
AddGen(3,EXPRESSION,DIVIDE,EXPRESSION);
AddGen(1,IDENTI);
AddGen(1,NUMBER);
}
PStackToken *PSnow = NULL;
LexToken *gettoken = NULL;
PStackToken *PStail = NULL;
PStackToken* Parse(char *Source)
{
static int sizeLexToken = sizeof(LexToken);
Generator *pgennow = NULL;//查找产生式时使用
LexToken *pstart = (LexToken*)malloc(sizeLexToken);//不检查合法性
Priority PrioCmpRlt = UN;
InitGenerator();
pstart->strName = NULL;
pstart->type = JINGHAO;
PStackPush(pstart);
while (gettoken = GetNextToken(Source))
{
if (PStop->ptoken->type == EXPRESSION)
{
PSnow = PStop->pr;
}
else
{
PSnow = PStop;
}
while ((PrioCmpRlt = PrioCmp(PSnow->ptoken->type, gettoken->type)) == GT)//PSnow未作检查,找到最左素短语尾部
{
while (1)//查找最左素短语头部
{
PStail = PSnow;
PSnow = PSnow->pr;
if (PSnow->ptoken->type == EXPRESSION)//未做合法性检查
{
PSnow = PSnow->pr;
}
if (PrioCmp(PSnow->ptoken->type, PStail->ptoken->type) == LS)
{//归约
int i;
PStackToken *pst;
pgennow = GLhead;
while(pgennow)
{
pst = PSnow->nt;
for (i=0; i<pgennow->size && pst!=PStop->nt; i++)
{
if (pst->ptoken->type != pgennow->gen[i])
break;
pst = pst->nt;
}
if(i==pgennow->size && pst==PStop->nt)//找到了产生式
{
LexToken *pExp = (LexToken*)malloc(sizeof(LexToken));
pst = PSnow->nt;
pExp->strName = NULL;
pExp->type = EXPRESSION;
PStop = PSnow;
PStackPush(pExp);//插入一个Expression节点
PStop->child = pst;//为该节点建立树
pst->pr = NULL;
break;
}
pgennow = pgennow->nt;
}
//在这里考虑无法归约的情况
}
break;
}
// break;
}
if (PrioCmpRlt == LS)
{
PStackPush(gettoken);
continue;
}
if (PrioCmpRlt == EQ)
{
if (PSnow->ptoken->type == JINGHAO)
{
//识别
break;
}
else
{
PStackPush(gettoken);
continue;
}
}
}
return PStop;
}
-------------------------------
C++编写的词法分析程序
这个是我编译原理课程设计的 内容,呵呵 我遍的是词法分析,基本的功能都能够实现,如词法分析,词法查错,删除无实质意义的字符等,不懂编译的就不用看了,编译真的很难!!!不过好象没什么用
#include<iostream.h>
#include<ctype.h>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#define ID 6
#define INT 7
#define LT 8
#define LE 9
#define EQ 10
#define NE 11
#define GT 12
#define GE 13
#define FZ 14
#define DEV 15
struct KeyWord //关键字结构
{
char *word;
int id;
};
KeyWord keyword[]={ //关键字数组
{"begin",1},
{"end",2},
{"if",3},
{"then",4},
{"else",5},
{"integer",16},
{"float",17},
{"double",18}
};
char TOKEN[20];
int graphnum=1; //记录错误所在的位置
int lookup(char *string);
void out(int id ,char *string);
void report_error(char ERR_CH);
bool isalpha(char c) ;
bool isdigit(char c);
bool isalnum(char c);
void scanner_example(FILE *fp);
int lookup(char *string)
{
for(int i=0;i<sizeof(keyword)/sizeof(KeyWord);i++)
{
if(strcmp(string,keyword[i].word)==0)
return keyword[i].id;
}
return 0;
}
void out(int id ,char *string)
{
printf("(%d,%s)\n",id,string);;
}
void report_error(char ERR_CH) //错误处理程序
{
printf("undeclared identifler %c int %d line!\n",ERR_CH,graphnum);
}
bool isalpha(char c)
{
if( (c>='a'&&c<='z') || (c>='A'&&c<='Z') )
return true;
else
return false;
}
bool isdigit(char c)
{
if(c>='0'&&c<='9')
return true;
else
return false;
}
bool isalnum(char c)
{
if( isalpha(c) || isdigit(c) )
return true;
else
return false;
}
void scanner_example(FILE *fp)
{
char ch;
int i,c;
while(!feof(fp))
{
ch=fgetc(fp);
if(isalpha(ch))
{
TOKEN[0]=ch;
ch=fgetc(fp);
i=1;
while(isalnum(ch))
{
TOKEN[i]=ch;
i++;
ch=fgetc(fp);
}
TOKEN[i]='\0';
fseek(fp,-1,1);
c=lookup(TOKEN);
if(c==0)
out (ID,TOKEN);
else
out (c," ");
}
else if(isdigit(ch))
{
TOKEN[0]=ch;
ch=fgetc(fp);
i=1;
while(isdigit(ch))
{
TOKEN[i]=ch;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -