📄 scanner.cpp
字号:
// Scanner.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include<stdio.h>
#include<string.h>
#include<conio.h>
#include<stdlib.h>
#include<ctype.h>
#define IDN 100 //标识符
#define INT8 101 //int8
#define INT10 102 //int10
#define INT16 103 //int16
#define REAL8 104 //real8
#define REAL10 105 //real10
#define REAL16 106 //real16
#define ADD 107 // +
#define SUB 108 // -
#define MUL 109 // *
#define DIV 110 // /
#define GT 111 // 〉
#define LT 112 // 〈
#define EQ 113 // =
#define SLP 114 // (
#define SRP 115 // )
#define COL 116 // ;
#define IF 117 //if
#define THEN 118 //then
#define ELSE 119 //else
#define WHILE 120 //while
#define DO 121 //do
#define TRUE 1
#define FALSE 0
int tempt=0;
int length=0;
typedef struct kinds{
int code;
//int value;
char *svalue;
};
kinds link[100];
char word[200]; //存放输入字符串,相当于缓冲区
int base=0; //单词开始指针
int search=0; //扫描指针
char* reserveWord[]={"if","then","else", "while", "do"}; //关键字
char* codeWord[]={"IDN","INT8","INT10","INT16","REAL8","REAL10","REAL16",
"ADD","SUB","MUL","DIV","GT","LT","EQ","SLP","SRP","COL",
"IF","THEN","ELSE","WHILE","DO"};//种类助记符
char getOneChar() //读取一个字符
{
char ch;
ch=word[base];
base++;
return ch;
}
void retract()
{
base--;
}
int isAlpha(char ch)//判断是否为一个字母
{
if((ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z')) return TRUE;
return FALSE;
}
int isDigit(char ch)//判断是否为一个数字
{
if(ch>='0'&&ch<='9') return TRUE;
return FALSE;
}
int isKeyword(char *token)//判断是否为一个关键字
{
int i=0;
int j=0;
for(i=0;i<=4;i++)
{
j=strcmp(token,reserveWord[i]);//关键字标识符
if(j==0) return i+IF;
}
return IDN; //普通标识符
}
kinds scan(void)
{
kinds kind; //最终的token
int i=0; //当前字符的下标
//int number; //token的属性值
char ch; //当前的字符
char *token; //当前的字符串
token=(char *)malloc(20);
ch=getOneChar();
//判断出否为是标识符
if(isAlpha(ch))
{
while(isalpha(ch)||isdigit(ch) )
{
token[i]=ch;token[i+1]='\0';i++;ch=getOneChar();
}
if(ch=='_'||ch=='.')
{
token[i]=ch;token[i+1]='\0';i++;ch=getOneChar();
while(isalpha(ch)||isdigit(ch) )
{
token[i]=ch;token[i+1]='\0';i++;ch=getOneChar();
}
}
retract();
kind.code=isKeyword(token); kind.svalue=token;
//if(kind.code==100) printf("\nIDN %8s",token);//普通的标识符
//else printf("\n%s _",token);//关键字
return kind;
}
//判断出是否为数字
else if(isDigit(ch))
{
if(ch=='0')
{
token[i]=ch;token[i+1]='\0';i++;ch=getOneChar();
//判断16进制
if(ch=='x'||ch=='X')
{
token[i]=ch;token[i+1]='\0';i++;ch=getOneChar();
if(ch>='0'&&ch<='9'||ch>='a'&&ch<='f')
{
while(ch>='0'&&ch<='9'||ch>='a'&&ch<='f')
{ token[i]=ch;token[i+1]='\0';i++;ch=getOneChar();}
if(ch=='.')
{
token[i]=ch;token[i+1]='\0';i++;ch=getOneChar();
while(ch>='0'&&ch<='9'||ch>='a'&&ch<='f')
{
token[i]=ch;token[i+1]='\0';i++;ch=getOneChar();
}
retract();
kind.code=REAL16; kind.svalue=token;
//printf("\nREAL16 %s",token);
return kind;
}
else
{
retract();
//sscanf(token,"%x",&number); //转化成值
//kind.value=number;
//printf("\nINT16 %d",number);
kind.code=INT16; kind.svalue=token;
//printf("\nINT16 %s",token);
return kind; //16进制
}
}
else printf("0x:判断16进制时,发生错误");//报错:错误的16进制
}
//判断8进制
else if(ch>='0'&&ch<='7')
{
while(ch>='0'&&ch<='7')
{
token[i]=ch;token[i+1]='\0';i++;ch=getOneChar();
}
if(ch=='.')
{
token[i]=ch;token[i+1]='\0';i++;ch=getOneChar();
while(ch>='0'&&ch<='7')
{
token[i]=ch;token[i+1]='\0';i++;ch=getOneChar();
}
retract();
kind.code=REAL8; kind.svalue=token;
//printf("\nREAL8 %s",token);
return kind;
}
else
{
retract();
//sscanf(token,"%o",&number);//转化成值
//kind.value=number;
//printf("\nINT8 %d",number);
kind.code=INT8; kind.svalue=token;
//printf("\nINT8 %s",token);
return kind; //8进制
}
}
else //以0开头的十进制
{
if(ch=='.')
{
token[i]=ch;token[i+1]='\0';i++;ch=getOneChar();
while(ch>='0'&&ch<='9')
{
token[i]=ch;token[i+1]='\0';i++;ch=getOneChar();
}
retract();
kind.code=REAL10; kind.svalue=token;
//printf("\nREAL10 %s",token);
return kind;
}
else
{
retract();
//number=0;
//kind.value=number;
//printf("\nINT10 0");
kind.code=INT10;kind.svalue=token;
//printf("\nINT10 %s",token);
return kind; //恰好是0
}
}
}
//判断非0开头的10进制
else
{
while(ch>='0'&&ch<='9')
{
token[i]=ch;token[i+1]='\0';i++;ch=getOneChar();
}
if(ch=='.')
{
token[i]=ch;token[i+1]='\0';i++;ch=getOneChar();
while(ch>='0'&&ch<='9')
{
token[i]=ch;token[i+1]='\0';i++;ch=getOneChar();
}
retract();
kind.code=REAL10; kind.svalue=token;
//printf("\nREAL10 %s",token);
return kind;
}
else
{
retract();
//sscanf(token,"%o",&number);//转化成值
//kind.value=number;
//printf("\nINT10 %s",token);
kind.code=INT10; kind.svalue=token;
//printf("\nINT10 %s",token);
return kind; //10进制
}
}
}
//判断运算符和分隔符
else if(ch=='+'){
kind.code=ADD;kind.svalue="+";
//printf("\n+ _ ");
return kind;
}
else if(ch=='-'){
kind.code=SUB;kind.svalue="-";
//printf("\n- _ ");
return kind;
}
else if(ch=='*'){
kind.code=MUL;kind.svalue="*";
//printf("\n* _ ");
return kind;
}
else if(ch=='/'){
kind.code=DIV;kind.svalue="/";
//printf("\n/ _ ");
return kind;
}
else if(ch=='>'){
kind.code=GT;kind.svalue=">";
//printf("\n> _ ");
return kind;
}
else if(ch=='<'){
kind.code=LT;kind.svalue="<";
//printf("\n< _ ");
return kind;
}
else if(ch=='='){
kind.code=EQ;kind.svalue="=";
//printf("\n= _ ");
return kind;
}
else if(ch=='('){
kind.code=SRP;kind.svalue="(";
//printf("\n( _ ");
return kind;
}
else if(ch==')'){
kind.code=SLP;kind.svalue=")";
//printf("\n) _ ");
return kind;
}
else if(ch==';'){
kind.code=COL;kind.svalue=";";
//printf("\n; _ ");
return kind;
}
else if(ch==' '){
kind.code=0;
return kind;
}
else{ //报错
printf("\nI don't know! ");
}
//kind.value=0;
//free(token);
kind.code=0;
return kind;
}
void main()
{
int index=0;
kinds kind;
//gets(word);
FILE *fp;
if((fp=fopen("xinjian.txt","r"))==NULL)
{
printf("打不开文件!\n");
}
fgets(word,200,fp);
printf("%s\n",word);
fclose(fp);
while(base<strlen(word))
{
kind=scan();
if(kind.code!=0) link[index++]=kind;
}
length=index;base=0;
for(int m=0;m<index;m++)
printf("%-8s %-8s\n",codeWord[link[m].code-100],link[m].svalue);
printf("词法分析到此结束!\n");
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -