词法分析
前一段时间一直在忙上机的事情,连续2周上机四次,现在才有时间整理
废话不多说,上思路:
首先我是以这个 类别和种别码 作为标准进行分类。
/*
单词符号 种别码 单词符号 种别码 单词符号 种别码
bengin 1 if 2 then 3
while 4 do 5 end 6
main 7 int 8 float 9
for 10 else 11 double 12
char 13 break 14 continue 15
标识符 16 整数 17 + 18
- 19 * 20 # 21
% 22 != 23 < 24
<> 25 <= 26 > 27
>= 28 = 29 == 30
; 31 ( 32 ) 33
! 34 / 35 " 36
*/
当然也可以进行添加 ,只是需要在switch-case里面添加对应的case而已;
写代码的时候需要注意的是 ,分析每一个类别是否要进入main里面的分析循环
代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define _KEY_WORD_END "waiting for your expanding" /*定义结束关键字*/
#define MAX_SIZE 225
typedef struct {
int typenum;
char *word;
}WORD;
WORD *scanner(); //词法扫描函数,获得一个单词
char m_getch();
void getbc();
void concat();
int letter();
int digit();
int reserve();
void retract();
char *dtb();
char input[MAX_SIZE]; //输入缓冲区
char token[MAX_SIZE]=""; //单词缓冲区
int p_input; //输入缓冲区指针
int p_token; //单词缓冲区指针
/*
单词符号 种别码 单词符号 种别码 单词符号 种别码
bengin 1 if 2 then 3
while 4 do 5 end 6
main 7 int 8 float 9
for 10 else 11 double 12
char 13 break 14 continue 15
标识符 16 整数 17 + 18
- 19 * 20 # 21
% 22 != 23 < 24
<> 25 <= 26 > 27
>= 28 = 29 == 30
; 31 ( 32 ) 33
! 34 / 35 " 36
程序能识别注释,且将其过滤掉
*/
char ch; //当前读入字符
char * rwtab[] = {"begin","if","then","while","do","end","main","int","float","for","else","double","char","break","continue","printf"} ;
int main(){
int over = 1;
WORD * oneword = new WORD;//已经测试可以使用 new
printf("Enter your words(end with $):\n");
scanf("%[^$]s",input);
p_input = 0;
printf("\nYour words : \n%s\n",input);
while(over < 1000 && over != -1){
oneword = scanner(); //获得一个单词
if(oneword->typenum < 1000)
printf("(% d, % s)\n",oneword->typenum,oneword->word);//打印种别码和自生的值
over = oneword->typenum;
}
printf("\n press $ to exit:");
scanf("%[^$]s",input);
return 0;
}
char m_getch(){ //从输入缓存区读取一个字符到ch中
ch = input[p_input];
p_input = p_input + 1;
// printf("-------%s\n",input);
return (ch);
}
void getbc(){ //去掉空白部分
while(ch==' '||ch == 10){
ch = input[p_input];
p_input += 1;
}
}
void concat(){ //拼接单词
token[p_token] = ch;
p_token += 1;
token[p_token] = '\0';
}
int letter(){ //判断是字母
if(ch >= 'a'&&ch <= 'z'||ch >= 'A'&&ch <= 'Z') return 1;
return 0;
}
int digit(){ //判断是数字
if(ch >= '0'&&ch <= '9')return 1;
else return 0;
}
int reserve(){ //检索关键字表格
int i = 0;
while(strcmp(rwtab[i],_KEY_WORD_END)){
if(!strcmp(rwtab[i],token)){
return (i + 1);
}
if(i>strlen(*rwtab)) break;
i = i + 1;
}
return 16;
}
void retract(){ //回退一个字符
p_input = p_input - 1;
}
char *dbt(){ //数字转换成二进制
return NULL;
}
WORD *scanner(){
WORD *myword = new WORD;
myword->typenum = 10;
myword->word = "";
p_token = 0;
m_getch();
getbc();
if(letter()){
while(letter()||digit()){
concat(); //拼接单词
m_getch(); //从输入缓存区读取一个字符到ch中
}
retract(); //回退一个字符
myword->typenum = reserve();
myword->word = token;
return (myword);
}
else if(digit()){
while(digit()){
concat();
m_getch();
}
retract();
myword->typenum = 17;
myword->word = token;
return (myword);
}
else switch(ch){
case '+': myword->typenum = 18;
myword->word = "+";
return (myword);
break;
case '-': myword->typenum = 19;
myword->word = "-";
return (myword);
break;
case '*': myword->typenum = 20;
myword->word = "*";
return (myword);
break;
case '#': myword->typenum = 21;
myword->word = "#";
return (myword);
break;
case '%': myword->typenum = 22;
myword->word = "%";
return (myword);
break;
case ';': myword->typenum = 31;
myword->word = ";";
return (myword);
break;
case '(': myword->typenum = 32;
myword->word = "(";
return (myword);
break;
case ')': myword->typenum = 33;
myword->word = ")";
return (myword);
break;
case '!': m_getch();
if(ch == '='){
myword->typenum = 23;
myword->word = "!=";
return (myword);
}
retract();
myword->typenum = 34;
myword->word = "!";
return (myword);
break;
case '<': m_getch();
if(ch == '='){
myword->typenum = 26;
myword->word = "<=";
return (myword);
}
if(ch == '>'){
myword->typenum = 25;
myword->word = "<>";
return (myword);
}
retract();
myword->typenum = 24;
myword->word = "<";
return (myword);
break;
case '>': m_getch();
if(ch == '='){
myword->typenum = 28;
myword->word = ">=";
return (myword);
}
retract();
myword->typenum = 27;
myword->word = ">";
return (myword);
break;
case '=': m_getch();
if(ch == '='){
myword->typenum = 30;
myword->word = "==";
return (myword);
}
retract();
myword->typenum = 29;
myword->word = "=";
return (myword);
break;
case'\0': myword->typenum=1000; //当读取到最后一个字符串的时候 ,为 \0 ,程序会当成无法辨别的程序,故而需要一个case来处理
myword->word="OVER";
return(myword);
break;
case '/': m_getch();
if(ch == '*'){
while(1){
m_getch();
if(ch == '*'){
m_getch();
if(ch == '/')
break;
}
}
myword->typenum = 1000;
myword->word = NULL;
return (myword);
}
else if(ch == '/'){
while(1){
m_getch();
if(ch == '\n')
break;
}
myword->typenum = 1000;
myword->word = NULL;
return (myword);
}
retract();
myword->typenum = 35;
myword->word = "/";
return (myword);
break;
case '"': myword->typenum = 36;
myword->word = " “";
return (myword);
break;
default: myword->typenum = -1;
myword->word = "ERROR";
return (myword);
}
}