📄 词法分析.cpp
字号:
// 词法分析.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "cifa.h"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
//字母表
char letter[52] = {'a','b','c','d','e','f','g','h','i','j','k','l','m',
'n','o','p','q','r','s','t','u','v','w','x','y','z',
'A','B','C','D','E','F','G','H','I','J','K','L','M',
'N','O','P','Q','R','S','T','U','V','W','X','Y','Z'
};
//关键字表
char* keyword[11] = {"begin","end","if","then","else","for",
"do","while","and","or","not"
};
//数字表
char number[10]={'0','1','2','3','4','5','6','7','8','9'};
//存放已经分析字符的缓冲区
char buff[10];
//将缓冲置为空
void setNull()
{
for(int i=0; i<=9; i++)
buff[i] = '#';
}
//判断是否为空格,回车,换行
bool isSpace(char ch)
{
bool succ = false;
if(ch==' '||ch=='\n'||ch=='\r')
succ = true;
return succ;
}
//判断是否为字母
bool isLetter(char ch)
{
bool succ = false;
for(int i=0; i<52; i++)
if(ch==letter[i])
succ = true;
return succ;
}
//判断是否为数字
bool isNumber(char ch)
{
bool succ = false;
for(int i=0; i<10; i++)
if(ch==number[i])
succ = true;
return succ;
}
//判断是否为保留字
int isKeyword(const char* str){
int succ = 0;
for(int i=0; i<11; i++)
if(strcmp(str,keyword[i])==0){
succ = i+1;
break;
}
return succ;
}
//将字符转统一换为小写
char getLetter(FILE *fp)
{
return tolower(fgetc(fp));
}
//出错处理
void Error(FILE *fp, char ch)
{
fprintf(fp, "Error occur:\n");
fprintf(fp, "%c...\n", ch);
fprintf(fp, "^\n");
}
//输出分析结果
void Print(int type,char* b)
{
printf("<%d,",type);
printf("%s",b);
printf(">\n");
}
//词法分析过程
void Analysis(FILE *infile, FILE *outfile)
{
char ch;
int i,isKey;
do{
//首先剔除空格符号
do{
ch = getLetter(infile);
//亦可用系统函数isspace()来实现
}while(isSpace(ch));
if(isLetter(ch)){
buff[0] = ch;
ch = getLetter(infile);
i = 1;
while (isLetter(ch) || isNumber(ch)){
buff[i] = ch;
i++;
ch = getLetter(infile);
}
buff[i] = '\0';
fseek(infile,-1,1);
isKey = isKeyword(buff);
if(isKey == 0){
Print(ID,buff);
fprintf(outfile, "%d,%s\n", ID, buff); //标识符
}else{
Print(isKey,buff);
fprintf(outfile, "%d,%s\n", isKey, buff); //关键字
}
}else{
if(isNumber(ch)){
buff[0] = ch;
ch = getLetter(infile);
i = 1;
while (isNumber(ch)){
buff[i] = ch;
i++;
ch = getLetter(infile);
}
buff[i] = '\0';
fseek(infile, -1, 1);
Print(INT,buff);
fprintf(outfile, "%d,%s\n", INT, buff);
}else{
switch(ch){
case '<':
{
ch = getLetter(infile);
if(ch == '='){
Print(LE,"<=");
fprintf(outfile, "%d,%s\n", LE, "<=");
}
else if(ch == '>'){
Print(NE,"<>");
fprintf(outfile, "%d,%s\n", NE, "<>");
}
else {
fseek(infile, -1, 1);
Print(LT,"<");
fprintf(outfile, "%d,%s\n", LT, "<");
}
break;
}
case '=':
{
Print(EQ,"=");
fprintf(outfile, "%d,%s\n", EQ, "=");
break;
}
case '>':
{
ch = getLetter(infile);
if (ch == '='){
Print(GE,">=");
fprintf(outfile, "%d,%s\n", GE, ">=");
}else{
fseek(infile, -1, 1);
Print(GT,">");
fprintf(outfile, "%d,%s\n", GT, ">");
}
break;
}
case ':':
{
ch = getLetter(infile);
if (ch == '=') {
Print(FUZHI,":=");
fprintf(outfile, "%d,%s\n", FUZHI, ":=");
}else{
fseek(infile, -1, 1);
Print(MAOHAO,":");
fprintf(outfile, "%d,%s\n", MAOHAO, ":");
}
break;
}
case '/':
{
ch = getLetter(infile);
if (ch == '*') {
Print(ZHUSHI_BEGIN,"/*");
fprintf(outfile, "%d,%s\n", ZHUSHI_BEGIN, "/*");
char zhushi[20];
int j=0;
ch = getLetter(infile);
while(ch!='*'){ //注释的内容
if(ch!='\r'&&ch!='\n'){
zhushi[j]=ch;
j++;
}
ch = getLetter(infile);
}
zhushi[j]='\0';
fseek(infile, -1, 1);
Print(ZHUSHI_CONTENT,zhushi);
fprintf(outfile, "%d,%s\n", ZHUSHI_CONTENT, zhushi);
}else{
fseek(infile, -1, 1);
Print(XIESHU,"/");
fprintf(outfile, "%d,%s\n", XIESHU, "/");
}
break;
}
case '+':
{
Print(JIAHAO,"+");
fprintf(outfile, "%d,%s\n", JIAHAO, "+");
break;
}
case '-':
{
Print(JIANHAO,"-");
fprintf(outfile, "%d,%s\n", JIANHAO, "-");
break;
}
case '*':
{
ch = getLetter(infile);
if (ch == '/') {
Print(ZHUSHI_END,"*/");
fprintf(outfile, "%d,%s\n", ZHUSHI_END, "*/");
}else{
fseek(infile, -1, 1);
Print(CHENHAO,"*");
fprintf(outfile, "%d,%s\n", CHENHAO, "*");
}
break;
}
case ';':
{
Print(FENHAO,";");
fprintf(outfile, "%d,%s\n", FENHAO, ";");
break;
}
case '(':
{
Print(ZUOKUOHAO,"(");
fprintf(outfile, "%d,%s\n", ZUOKUOHAO, "(");
break;
}
case ')':
{
Print(YOUKUOHAO,")");
fprintf(outfile, "%d,%s\n", YOUKUOHAO, ")");
break;
}
default:
{
if(ch != EOF){
Print(ERROR,"error");
Error(outfile, ch);
}
break;
}
}
}
}
}while(ch != EOF);
}
//主函数
int main(int argc, char* argv[])
{
FILE *infile, *outfile;
printf("***********************************************************************\n");
printf("***********************************************************************\n");
printf("** <文法描述> **\n");
printf("** 1:<标识符>→字母︱ <标识符>字母︱ <标识符>数字 **\n");
printf("** 2:<无符号整数>→数字︱ <无符号整数>数字 **\n");
printf("** 3:<单字符分界符> →+ ︱- ︱* ︱; ︱(︱) **\n");
printf("** 4:<双字符分界符>→<大于>=︱<小于>=︱<小于>>︱<冒号>=︱<斜竖>* **\n");
printf("** 5:<小于>→< **\n");
printf("** 6:<等于>→= **\n");
printf("** 7:<大于>→> **\n");
printf("** 8:<冒号> →: **\n");
printf("** 9:<斜竖> →/ **\n");
printf("** 保留字:begin end if then else for do while and or not **\n");
printf("***********************************************************************\n");
int c = 0;
do{
printf("\n***********************************************************************\n");
printf("\n请选择:1->开始词法分析 2->退出\n");
scanf("%d",&c);
if(c==1){
char in[20],out[20];
do{
printf("\n请输入需要分析的源文件路径:");
scanf("%s",&in);
printf("\n请输入保存分析结果的文件路径:");
scanf("%s",&out);
infile = fopen(in, "r");
outfile = fopen(out, "w");
if(infile==NULL)
printf("\n出错:未找到源文件,请再次输入源文件路径!\n\n");
}while(infile==NULL);
printf("\n下面是文件%s中文法的词法分析结果:\n\n",in);
Analysis(infile, outfile);
fprintf(outfile, "0,#");
fclose(infile);
fclose(outfile);
printf("\n词法分析已经结束,分析结果已经写到目录下的%s文件!\n",out);
}else if(c==2)
break;
else printf("请选择正确选项!\n");
}while(true);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -