/**************/
/* 词法分析器 */
/**************/
/*load.txt—一个词法分析器和语法分析器简单算术表达式*/
#include<stdio.h>
#include<ctype.h>
#include<string.h>
/*全局声明*/
/*变量*/
int charClass;
char lexeme[100];
char nextChar;
int lexLen;
int token;
int nextToken;
FILE *in_fp, *fopen();
/*函数声明*/
void addChar();
void getChar();
void getNonBlank();
int lex();
void expr();
void term();
void factor();
void ifstmt();
//void boolexpr();
//void statement();
/*字符类*/
#define LETTER 0
#define DIGIT 1
#define UNKNOWN 99
/*标记编码*/
#define INT_LIT 10
#define IDENT 11
#define ASSIGN_OP 20
#define ADD_OP 21
#define SUB_OP 22
#define MULT_OP 23
#define DIV_OP 24
#define MOD_OP 25
#define POWER_OP 26
#define LEFT_PAREN 27
#define RIGHT_PAREN 28
#define SEMICOLON_SIGN 29
#define IF_CODE 30
#define ELSE_CODE 31
#define NOR_OP 32
/*************************************************************/
/*主驱动程序*/
int main()
{
/*打开输入数据文件并处理其内容*/
if((in_fp = fopen("load.txt", "r")) == NULL)
printf("错误—无法打开load.txt \n");
else
{
FILE * in_fp = fopen("load.txt", "r");
char fstring[10];
while(fscanf(in_fp,"%s",fstring) != EOF)
{
getChar();
lex();
ifstmt();
//expr();
}
fclose(in_fp);
}
}
/*************************************************************/
/*lookup—查找运算符和圆括号并返回标记的函数*/
int lookup(char ch)
{
switch(ch)
{
case '(':
addChar();
nextToken = LEFT_PAREN;
break;
case ')':
addChar();
nextToken = RIGHT_PAREN;
break;
case '+':
addChar();
nextToken = ADD_OP;
break;
case '-':
addChar();
nextToken = SUB_OP;
break;
case '*':
addChar();
nextToken = MULT_OP;
break;
case '/':
addChar();
nextToken = DIV_OP;
break;
case '%':
addChar();
nextToken = MOD_OP;
break;
case '^':
addChar();
nextToken = POWER_OP;
break;
case ';':
addChar();
nextToken = SEMICOLON_SIGN;
break;
case '!':
addChar();
nextToken = NOR_OP;
break;
default:
addChar();
nextToken = EOF;
break;
}
return nextToken;
}
/*************************************************************/
/*addChar—将nextChar加入lexeme的函数*/
void addChar()
{
if(lexLen <= 98)
{
lexeme[lexLen++] = nextChar;
lexeme[lexLen] = 0;
}
else
printf("错误—词素太长 \n");
}
/*************************************************************/
/*getChar—获取下一个输入字符并确定其字符类的函数*/
void getChar()
{
if((nextChar = getc(in_fp)) != EOF)
{
if(isalpha(nextChar)) //如果nextChar是字母
charClass = LETTER;
else if (isdigit(nextChar)) //如果nextChar是数字
charClass = DIGIT;
else
charClass = UNKNOWN;
}
else
charClass = EOF;
}
/*************************************************************/
/*getNonBlank()—调用getChar直到返回非空格字符的函数*/
void getNonBlank()
{
while(isspace(nextChar)) //如果nextChar是空格
getChar();
}
/*************************************************************/
/*lex—一个用于算术表达式的简单词法分析器*/
int lex()
{
lexLen = 0;
getNonBlank();
switch(charClass)
{
/*分析标识符*/
case LETTER:
addChar();
getChar();
while(charClass == LETTER || charClass == DIGIT)
{
addChar();
getChar();
}
if(strcmp(lexeme,"if") == 0)
nextToken = IF_CODE;
else if(strcmp(lexeme,"else") == 0)
nextToken = ELSE_CODE;
else
nextToken = IDENT;
break;
/*分析整数字面值*/
case DIGIT:
addChar();
getChar();
while(charClass == DIGIT)
{
addChar();
getChar();
}
nextToken = INT_LIT;
break;
/*圆括号和运算符*/
case UNKNOWN:
lookup(nextChar);
getChar();
break;
/*EOF*/
case EOF:
nextToken = EOF;
lexeme[0] = 'E';
lexeme[1] = 'O';
lexeme[2] = 'F';
lexeme[3] = 0;
break;
} /*switch的结束*/
printf("下一个标记是: %d, 下一个词素是 %s\n", nextToken, lexeme);
return nextToken;
} /*函数lex的结束*/
/*****************************************************************************************************************************************/
/**************/
/* 语法分析器 */
/**************/
/* expr
分析以下规则生成的语言中的串:
<表达式> -> <项> { ( + | - ) <项> }
*/
void expr()
{
printf("进入<表达式>\n");
/*分析第一个项*/
term();
/*只要下一个标记是+或-,获取下一个标记并分析下一个项*/
while(nextToken == ADD_OP || nextToken == SUB_OP)
{
lex();
term();
}
printf("退出<表达式>\n");
} /*函数expr结束*/
/*************************************************************/
/* term
分析以下规则生成的语言中的串:
<项> -> <因子> { ( * | / | % | ^ ) <因子> }
*/
void term()
{
printf("进入<项>\n");
/*分析第一个因子*/
factor();
/*只要下一个标记是*或/或%或^,获取下一个标记并分析下一个因子*/
while(nextToken == MULT_OP || nextToken == DIV_OP || nextToken == MOD_OP || nextToken == POWER_OP)
{
lex();
factor();
}
printf("退出<项>\n");
} /*函数term结束*/
/*************************************************************/
/* factor
分析以下规则生成的语言中的串:
<因子> -> 标识符 | 整数常量 | ( <表达式> )
*/
void factor()
{
printf("进入<因子>\n");
/*确定是哪一个RHS*/
if(nextToken == IDENT || nextToken == INT_LIT)
/*获取下一个标记*/
lex();
/*如果RHS是(<表达式>),调用lex来跳过左圆括号,调用expr,检查右圆括号*/
else
{
if(nextToken == LEFT_PAREN)
{
lex();
expr();
if(nextToken == RIGHT_PAREN)
lex();
else
printf("错误—没有与'('匹配的')',请重新输入:\n");
} /* if(nextToken == …的结束 */
/*不是标识符、整数字面值、右圆括号 */
else
printf("错误—不符合语法规定,请重新输入:\n");
} /* else的结束 */
printf("退出<因子>\n");
} /* 函数factor结束 */
/*************************************************************/
/* 函数ifstmt
分析以下规则生成的语言中的串:
<if语句> -> if ( <布尔表达式> ) <语句> [ else <语句> ]
*/
void ifstmt()
{
/*确定第一个标记是'if'*/
if(nextToken != IF_CODE)
expr();
else
{
printf("进入<if语句>\n");
/*调用lex获得下一个标记*/
lex();
/*检查左圆括号*/
if(nextToken != LEFT_PAREN) //if后面没有括号
printf("错误—不符合语法规定,请重新输入:\n");
else
{
printf("进入<布尔表达式>\n");
/*调用expr分析布尔表达式*/
expr();
/*检查右圆括号*/
if(nextToken != RIGHT_PAREN)
printf("错误—没有与'('匹配的')',请重新输入:\n");
else
{
printf("退出<布尔表达式>\n");
printf("进入<THEN语句>\n");
/*调用expr分析then子句*/
expr();
/*如果接着是else,分析else子句*/
if(nextToken == ELSE_CODE)
{
printf("退出<THEN语句>\n");
printf("进入<ELSE语句>\n");
/*调用lex跳过else */
lex();
expr();
printf("退出<ELSE语句>\n");
} /* if(nextToken == ELSE_CODE)的结束 */
} /* if(nextToken != RIGHT_PAREN)的else的...的结束*/
} /* if(nextToken != LEFT_PAREN)的else的...的结束*/
printf("退出<if语句>\n");
} /* if(nextToken != IF_CODE)的else的...的结束*/
} /*ifstmt的结束*/