简易的词法分析器

阅读: 评论:0

简易的词法分析器

简易的词法分析器

    这学期学习编译原理,第一个实验就是做一个简易的词法分析器。

 自己写了一个,保存在这。以后需要的时候再来看看。

//     对于每一行输出的解释:
// 1.第一个为取出来的单词
// 2.第二个为该单词首字母出现的位置 [行: 列]
// 3.第三个为该单词的种类码:
//		   -1 错误 
//          1 关键字
//			2 自定义标识码
//			3 数字
//			4 常用符号
//			5 运算符
//			6.比较或赋值符号
//
//
//
//
//#include <cstdio>
#include <algorithm>
#include <queue>   //队列
#include <ctype.h>
#include<cstdlib>using namespace std;typedef struct word    //单词结构体
{int row;		//行int column;		//列int category;	//种别码char str[0];
}word;queue<word*>  words;   // 单词队列//关键字
const char* keys[] = { "if","else","for","while","do","return","break","continue","int","double","char","main" };//常用符号
const char* border[] = { ",",";","{","}","(",")","[","]","&" };//运算符
const char* arithmetic[] = { "+","-","*","/","%" };//比较符
const char* relation[] = { "<","<=","=","==","!=",">=",">" };// 单词转结构体
word* res_struct(int row, int column, int category, char* str, int n);// 词法分析器
int lexical_analyzer(FILE* fp);// 单词种类判断
int word_estimate(char* str, int n, int key, int row, int column);int main()
{FILE* fp = NULL;word *aword;if ((fp = fopen(&#", "r"))== NULL){printf("打不开文件n");return -1;}lexical_analyzer(fp);   //词法分析while (!pty())    //输出队列中的单词{aword = words.front();words.pop();printf(""%s" [%d:%d] %dn", aword->str, aword->row, aword->column, aword->category);}if (fp != NULL){fclose(fp);}return 0;
}/// <summary>
/// 单词转结构体
/// </summary>
/// <param name="row">行数</param>
/// <param name="column">列数</param>
/// <param name="category">种别码</param>
/// <param name="str">单词</param>
/// <param name="n">单词长度</param>
/// <returns>转换后的结构体</returns>
word* res_struct(int row, int column,int category, char* str, int n)
{word* a_word = (word*)malloc(sizeof(word) + n+1);if(a_word){a_word->column = column;a_word->row = row;a_word->category = category;strcpy(a_word->str, str);}return a_word;
}/// <summary>
/// 词法分析器
/// </summary>
/// <param name="fp">文件指针</param>
/// <returns>0 表示分析结束</returns>
int lexical_analyzer(FILE* fp)
{char cbuffer = fgetc(fp);//获得一个字符char tp[30] = { 0 };  //临时单词int row = 1;	//行int column = 1; //列int n = 0;      //单词长度int key = 0;	//单词模糊类型while (cbuffer != EOF)   //直到文件末尾{n = 0;if (isalpha(cbuffer) || cbuffer == '_')	//第一个字符为字母或下划线{while ((isalpha(cbuffer)) || (isdigit(cbuffer)) || cbuffer == '_') //读出整个单词{tp[n++] = cbuffer;cbuffer = fgetc(fp);column++;}tp[n] = '';key = 1;}else if (isdigit(cbuffer))				//第一个字符为数字{while (isdigit(cbuffer) || cbuffer == '.' || isalpha(cbuffer)){tp[n++] = cbuffer;cbuffer = fgetc(fp);column++;}tp[n] = '';key = 2;}else									//第一个字符为其他的{tp[0] = cbuffer;tp[1] = '';if (tp[0] == ' ')  // 空格符{column++;cbuffer = fgetc(fp);continue;}else if (tp[0] == 't')    //制表符  占4个位置{column += 4;cbuffer = fgetc(fp);continue;}else if (tp[0] == 'n')   //换行符{row++;column = 1;cbuffer = fgetc(fp);continue;}else if (tp[0] == '>' || tp[0] == '<' || tp[0] == '!' || tp[0] == '=')  //比较符{cbuffer = fgetc(fp);tp[1] = cbuffer;tp[2] = '';column++;if (tp[1] == '=')    //双字符比较符{cbuffer = fgetc(fp);column++;n = 2;}else{tp[1] = '';n = 1;}}else					//单字符比较符{cbuffer = fgetc(fp);n = 1;column++;}key = 3;}//单词判断word_estimate(tp, n, key, row, column - n);}return 0;
}/// <summary>
/// 单词种类判断
/// </summary>
/// <param name="str">单词</param>
/// <param name="n">单词长度</param>
/// <param name="key">单词模糊类型</param>
/// <param name="row">行</param>
/// <param name="column">列</param>
/// <returns>单词类型</returns>
int word_estimate(char* str, int n, int key, int row, int column)
{int i;if (key == 1)  //字符开头{for (i = 0; i < sizeof(keys) / sizeof(keys[0]); i++)   //关键字{if (strcmp(keys[i], str) == 0){words.push(res_struct(row, column, 1, str, n));return 1;}}words.push(res_struct(row, column, 2, str, n));     //自定义标识符return 2;}else if (key == 2)  //数字开头{int p = 0;		//E前面的点的个数int flag1 = 0;	//判断当前在E前面还是后面if (str[0] == '0' && n >= 2 &&(str[1]=='x' || str[1] == 'X'))  //0打头16进制{ if (n == 2){words.push(res_struct(row, column, -1, str, n));return -1;}for (i = 2; i < n; i++){if (str[1] == 'X'){if (!(isdigit(str[i]) || (str[i] >= 'A' && str[i] <= 'F'))){words.push(res_struct(row, column, -1, str, n));return -1;}}else{if (!(isdigit(str[i]) || (str[i] >= 'a' && str[i] <= 'f'))){words.push(res_struct(row, column, -1, str, n));return -1;}}}words.push(res_struct(row, column, 3, str, n));   //数字return 3;}	else if (str[0] == '0' && n >= 2 && str[1]!='.') //0打头8进制{for (i = 1; i < n; i++) {if (!(str[i] >= '0' && str[i] <= '7')){words.push(res_struct(row, column, -1, str, n));return -1;}}words.push(res_struct(row, column, 3, str, n));return 3;}else    //10进制{for (i = 0; i < n; i++){if (flag1 == 0)  //E前面{if (str[i] == 'e' || str[i] == 'E'){flag1 = 1;}else if (str[i] == '.' && p == 0){p = 1;}else if (str[i] == '.' && p == 1){words.push(res_struct(row, column, -1, str, n));return -1;}else if (isalpha(str[i])){words.push(res_struct(row, column, -1, str, n));return -1;}}else{if (!isdigit(str[i])){words.push(res_struct(row, column, -1, str, n));return -1;}}}words.push(res_struct(row, column, 3, str, n));return 3;}}else	//特殊字符{for (i = 0; i < sizeof(border) / sizeof(border[0]); i++){if (strcmp(str, border[i]) == 0){words.push(res_struct(row, column, 4, str, n));     //常用符号return 4;}}for (i = 0; i < sizeof(arithmetic) / sizeof(arithmetic[0]); i++){if (strcmp(str, arithmetic[i]) == 0){words.push(res_struct(row, column, 5, str, n));     //运算符return 5;}}for (i = 0; i < sizeof(relation) / sizeof(relation[0]); i++){if (strcmp(str, relation[i]) == 0){words.push(res_struct(row, column, 6, str, n));     //比较符return 6;}}}
}

本文发布于:2024-02-02 15:31:47,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170685910844731.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:词法   分析器   简易
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23