编译器DIY——读文件
编译器的前端词法分析:将源文件解析成一个个的单词流。为语法分析做准备。
在词法分析阶段,我们要做的就是将词分出来,而且确定单词的类型,一般的程序设计语言的单词符号能够份为下面5种:
1.keyword,如int,long等
2.标识符,用来表示各种名字,如常量名,变量名等
3.常数。各种类型的常数,如12。1.2等
4.运算符:如+,-,*,/等
5.界符,如“,”“;”等
那么在实际的过程中应该怎样来区分这5中类型,在后面的文章中我将详细讲到。
词法分析第一阶段。非常明显,须要从源文件里读取数据。考虑到如今的硬件内存都达到了2G及以上的标准,那么就将所有源文件读到内存中,并设置指针指向头位置。那么在随后的分词操作中,将直接操作指针就可以。在其它的编译器中,非常多类型都是从文件里按行读取然后对该行中的数据进行解析,这样做的优点就是空间的大大节省,特别是当内存紧凑的时候。而我之所以所有读取,不不过由于硬件的原因,另一个原因是在随后的分词中,我会相对简单一些。
我们先构造一个结构用来存储对源文件有关的操作:
struct File {
void *file;// 指向文件的指针
char *fileName;//文件名称
unsigned char *cursor;//光标的位置
unsigned char *first;//内存区的首地址
unsigned long size;//文件的大小
};
接着用一个函数来实现读取源文件的操作:
int readSourceFile(char *fileName) {
source.file = fopen(fileName, "r");
if (source.file == NULL) {
Error("Can not open file.\n");
return 0;
}
source.fileName = fileName;
fseek(source.file, 0, SEEK_END);
source.size = ftell(source.file);
source.first = malloc(source.size + 1);
if (source.first == NULL) {
Error("The file is too big");
fclose(source.file);
return 0;
}
fseek(source.file, 0, SEEK_SET);
source.size = fread(source.first, 1, source.size, source.file);
fclose(source.file);
source.first[source.size] = END_OF_FILE;
source.cursor = source.first;
return 1;
}
用fseek重定位文件的指针,ftell来取得指针对于文件首部的偏移量,从而得出文件的大小,接着开辟等量的空间,最后对文件结构体进行赋值
在编译器中由于要对错误进行处理,所以就将全部的出错函数封装起来。以便随时调用。
出错函数:
void Error(const char *format, ...)
{
va_list ap;
fprintf(stderr, "error:");
va_start(ap, format);
vfprintf(stderr, format, ap);
fprintf(stderr, "\n");
va_end(ap);
} void Warning(const char *format, ...)
{
va_list ap;
fprintf(stderr, "warning:");
va_start(ap, format);
vfprintf(stderr, format, ap);
fprintf(stderr, "\n");
va_end(ap); return;
}
最后我们来进行測试:
測试函数:
/*
* debug put all content from source file
* */
void putSrc(){
unsigned char *ch=source.first;
while(*ch != END_OF_FILE){
printf("%c", *ch++);
}
}
主函数:
int main() {
readSourceFile("test.txt");
putSrc();
}
到这里我们完毕了词法分析的第一步。在下篇文章中就是对源文件里的数据进行解析。
编译器DIY——读文件的更多相关文章
- 编译器DIY——词法分析
在上一篇文章中已经介绍了读文件的操作,那么这一篇文章中将会细致解释词法分析. 在源文件里解析出的单词流必须识别为保留字,标识符,常量,操作符和界符五大类 1.显然我们须要列举出全部的保留字,而这里与保 ...
- GoLang几种读文件方式的比较
GoLang提供了很多读文件的方式,一般来说常用的有三种.使用Read加上buffer,使用bufio库和ioutil 库. 那他们的效率如何呢?用一个简单的程序来评测一下: package main ...
- Python之路 day2 按行读文件
#1. 最基本的读文件方法: # File: readline-example-1.py file = open("sample.txt") while 1: line = fil ...
- java的读文件操作
java读取文件内容,可以作如下理解: 首先获得一个文件句柄,File file = new File():file即为文件句柄.两人之间联通电话网络了,就可以开始打电话了. 通过这条线路读取甲方的信 ...
- PHP使用feof()函数读文件的方法
这篇文章主要介绍了PHP使用feof()函数读文件的方法,以实例形式对比了正确与错误的用法,阐明了feof()函数的使用技巧,需要的朋友可以参考下 本文实例讲述了PHP使用feof()函数读文件的方法 ...
- Java基础之读文件——使用输入流读取二进制文件(StreamInputFromFile)
控制台程序,读取Java基础之读文件部分(StreamOutputToFile)写入的50个fibonacci数字. import java.nio.file.*; import java.nio.* ...
- c++中ifstream读文件的问题(关于eof())
今天帮别人找BUG,是一段关于c++读写文件的问题,使用的是ifstream与outstream类,关于ofstream与ifstream的用法,此处不再獒述,见代码: #include<ios ...
- python (11)文件的读写 按行读文件
读文件: 读取文件 f = open('\info.txt') fil = f.read() f.close() 按行读文件: f = open("info.txt") while ...
- Python学习入门基础教程(learning Python)--5.2 Python读文件基础
上节简单的说明了一下Pyhon下的文件读写基本流程,从本节开始,我们做几个小例子来具体展示一下Python下的文件操作,本节主要是详细讲述Python的文件读操作. 下面举一个例子,例子的功能是读取当 ...
随机推荐
- 《Haskell趣学指南》
<Haskell趣学指南> 基本信息 原书名:Learn You a Haskell for Great Good!: A Beginner's Guide 原出版社: No Starch ...
- 一次delete速度异常慢的处理过程
InnoDB delete from xxx速度暴慢原因 博客分类: database MySQLPythonMobile多线程SQL step1,一个简单的联系人表 CREATE TABLE `c ...
- 树莓派安装 Nginx + PHP7.0 + Pi Dashboard
之前我们介绍过树莓派搭建LNMP环境的方法,以及给树莓派装一个仪表盘来监控树莓派运行状态.近期有用户反馈树莓派最新版的系统已经无法找到 PHP5 的软件包了,这是因为新版本已经用 PHP7 替代了 P ...
- jQuery序列化表单数据 serialize()、serializeArray()及使用
1.serialize() 方法: serialize() 方法通过序列化表单值,创建 URL 编码文本字符串. 您可以选择一个或多个表单元素(比如 input 及/或 文本框),或者 form 元素 ...
- JDBC基本操作介绍
一 .JDBC主要的API介绍 JDBC为开发人员提供了一套标准的API,都是由JAVA语言编写的类和接口.用于连接数据库和执行SQL语句.JDBC也是JAVA核心类库的一部分,位于Java.sql包 ...
- 文本相似性计算总结(余弦定理,simhash)及代码
最近在工作中要处理好多文本文档,要求找出和每个文档的相识的文档.通过查找资料总结如下几个计算方法: 1.余弦相似性 我举一个例子来说明,什么是"余弦相似性". 为了简单起见,我们先 ...
- mysql 索引长度的限制
myisam表,单列索引,最大长度不能超过 1000 bytes: innodb表,单列索引,最大长度不能超过 767 bytes: utf8 编码时 一个字符占三个字节 varchar 型能建 ...
- 给电脑装完系统之后,发现U盘少了几个G!
我的U盘是8个G的,有一次用U盘给电脑装完系统,过了几天后再次用的时候发现U盘 突然少了几个G,刚开始不知道怎么回事,然后就格式化U盘,但是格式化之后没有任何 变化. 在网上搜了一下,说是U盘有可能被 ...
- python xlrd简单读取excel
import xlrd #打开文件 book = xlrd.open_workbook ('Status.xlsx') #获取数据表 table1 = book.sheets()[0] table2 ...
- 设计模式之Programming to an Interface, not anImplementation 程序指向接口,而不是实现
Class inheritance is basically just a mechanism for extending an application's functionality by reus ...