#include <stdio.h>
#include "symbol_table_def.h"
//前面的那个词法和文法说明只是大概的说明,现在又有了改动,把指针运算符改为了@,把取地址运算符改为了$
//但是类型声明的时候的指针类型仍然是*
//现在所有的符号都用了,除了让人恶心的逗号和问号
//现在开始定义词法单元的枚举类型
enum lex_type
{
name,//代表字符串,包括所有的关键字和变量声明
delimit,//代表分号,以及大括号
char_type,//代表字符
an_operator,//代表操作符
constant,//代表常量
string_phrase,//代表字符串
new_line//代表换行,因为在处理的时候换行是一个很重要的符号
};
enum basic_operator_type
{
array_op=,//代表数组分量运算
parenthesis,//代表括号
p_str_sub,//代表结构体指针分量运算
str_sub,//代表结构体分量运算
not,//代表!
bit_rev,//代表~
get_adr,//代表$
get_mem,//代表@
type_cast,//代表强制类型转换
negative,//代表负号运算
get_size,//代表sizeof
multi,//代表乘法
div,//代表除法
module,//代表模
add,//代表加法
minus,//代表减法
left_shift,//左移
right_shift,//右移
larger,//大于
smaller,//小于
lar_eqa,//大于等于
sma_eqa,//小于等于
equal,//等于
nequal,//不等于
bit_and,//&
bit_xor,//^
bit_or,//|
and,//&&
or// ||
}; struct first_lex_token
{
enum lex_type current_lex_type;//在第一遍处理的时候我们把所有的词素分为前面所说的六种
char* token_name;
};
struct first_token_chain//这个链表将所有的词法单元串联起来
{
struct first_lex_token* current_first_token;
struct first_token_chain* next;
};
struct first_token_chain* first_chain_head=NULL;//这里是所有节点的头节点
struct first_token_chain* first_chain_tail=NULL;//这里是所有节点的末尾节点,为了插入用.
//在第一趟处理的时候我们开两个2000个字节的缓冲区,用来读文件,并不断的切换
//为了表明文件的结束,我们找来了我们的老朋友 '17' ,我们用这个字符来表示缓冲区的文件末尾
char end_of_file=;
char* buff_zone[];//这个代表两个缓冲区
int buffer_pointer;//这个代表在缓冲区内的偏移
int file_read_byte;//这个代表在读取文件到缓冲区的时候,读取了多少个字符
int buff_zone_index;//代表使用的是那一个缓冲区
char* current_buff;//这个代表当前的缓冲区
int seek_begin(void )
{
//吃掉所有的空格和制表符
while(buffer_pointer<)
{
switch(*(buffer_zone[buffer_zone_index]+buffer_pointer))
{
case :
return -;//直接返回,文件已经处理完毕了
break;
case ' ':
buffer_pointer++;
break;
case '\t':
buffer_pointer++;
break;
default:
break;
}
}
if(buffer_pointer==)//越过缓冲区了
{
buffer_zone_index=-buffer_zone_index;//切换缓冲区
current_buff=buff_zone[buff_zone_index];
file_read_byte=fread(current_buff,sizeof(char),,input_file_name);
if(file_read_byte!=)//如果碰到文件的结束了
{
*(current_buff+file_read_byte)=;//标记为文件末尾
//因为我们遇到的是字符文件,所以不会出现17这个字符
}
buffer_pointer=;
//重新开始读取输入,这里我们默认制表符和空格符不会占用整个缓冲
//吃掉所有的空格和制表符
while(buffer_pointer<)
{
switch(buffer_zone[buffer_zone_index]+buffer_pointer)
{
case :
return -;//直接返回,文件已经处理完毕了
break;
case ' ':
buffer_pointer++;
break;
case '\t':
buffer_pointer++;
break;
default:
break;
}
}
} return ;//代表正常的返回
}
int lex_char_type(char current)//返回当前字符的前缀集
{
char test;
test=current;
if((test>='a'&&test<='z')||(test>='A'&&test<='Z')||(test=='_'))
{
return ;//代表名字
}
else
{
if(test>=''&&test<='')
{
return ;//数字
}
else
{
if(test==';'||test=='{'||test=='}')
{
return ;//代表分隔符
}
else
{
if(test=='\'')
{
return ;//代表字符
}
else
{
if(test=='\"')
{
return ;//代表字符串
}
else
{
return ;//代表运算符
}
}
}
}
}
} void first_procedure(FILE* input_file_name)
{
char* temp_name;//代表词法单元的内容
int token_length;//代表读取的词法单元的长度
int lex_mode;//代表开始字符所处的token种类
int seek_return;
char current_char;
int for_i,for_j;
struct first_lex_token* temp_token;
struct first_token_chain token_chain_node;
current_buff=malloc(sizeof(char)*);
buff_zone[]=current_buff;
buff_zone[]=current_buff+;
//这里我们其实上把一个4000的缓冲区分裂为两个缓冲区了,这样可以让这两个缓冲区的空间连续
file_read_byte=fread(current_buff,sizeof(char),,input_file_name);
if(file_read_byte!=)//如果碰到文件的结束了
{
*(current_buff+file_read_byte)=;//标记为文件末尾
//因为我们遇到的是字符文件,所以不会出现17这个字符
}
buff_zone_index=;//首先使用第一个缓冲区
buffer_pointer=;
seek_return=seek_begin();
while(seek_return!=-)//只要还没有到达末尾
{
current_char=*(buff_zone[buff_zone_index]+buffer_pointer);
lex_mode=lex_char_type(current_char);
switch(lex_mode)
{
case ://代表名字
token_length=;
while((current_char>='a'&&current_char<='z')||(current_char>='A'&&current_char<='Z')||current_char=='_')
{
token_length++;
buffer_pointer++;
if(buffer_pointer==)
{
buff_zone_index=-buff_zone_index;
current_buff=buff_zone[buff_zone_index];
file_read_byte=fread(current_buff,sizeof(char),,input_file_name);
if(file_read_byte!=)//如果碰到文件的结束了
{
*(current_buff+file_read_byte)=;//标记为文件末尾
//因为我们遇到的是字符文件,所以不会出现17这个字符
}
buffer_pointer=;
}
current_char=current_buff[buffer_pointer];
}
temp_name=malloc(sizeof(char)*(token_length+));
if(token_length<=buffer_pointer)
{
for(for_i=;for_i<token_length;for_i++)
{
temp_name[for_i]=current_buff[buffer_pointer-token_length+for_i];
}
}
else
{
current_buff=buff_zone[-buff_zone_index];
for_j=token_length-buffer_pointer;
for(for_i=;for_i<for_j;for_i++)
{
temp_name[for_i]=current_buff[-for_j+for_i];
}
current_buff=buff_zone[buff_zone_index];
for(for_i=;for_i<buffer_pointer;for_i++)
{
temp_name[for_j+for_i]=current_buff[for_i];
}
}
temp_name[token_length]='\0';
temp_token=malloc(sizeof(struct first_lex_token));
temp_token->token_name=temp_name;
if(strcmp("sizeof",temp_name)==)
{
temp_token->current_lex_type=an_operator;
}
else
{
temp_token->current_lex_type=name;
}
break;
case ://对应数字常量的情况
token_length=;
while((current_char>=''&&current_char<='')||(current_char>='A'&&current_char<='F')||\
(current_char>='a'&&current_char<='f')||current_char=='x'||current_char=='X'||current_char=='.')
{
token_length++;
buffer_pointer++;
if(buffer_pointer==)
{
buff_zone_index=-buff_zone_index;
current_buff=buff_zone[buff_zone_index];
file_read_byte=fread(current_buff,sizeof(char),,input_file_name);
if(file_read_byte!=)//如果碰到文件的结束了
{
*(current_buff+file_read_byte)=;//标记为文件末尾
//因为我们遇到的是字符文件,所以不会出现17这个字符
}
buffer_pointer=;
}
current_char=current_buff[buffer_pointer];
}
temp_name=malloc(sizeof(char)*(token_length+));
if(token_length<=buffer_pointer)
{
for(for_i=;for_i<token_length;for_i++)
{
temp_name[for_i]=current_buff[buffer_pointer-token_length+for_i];
}
}
else
{
current_buff=buff_zone[-buff_zone_index];
for_j=token_length-buffer_pointer;
for(for_i=;for_i<for_j;for_i++)
{
temp_name[for_i]=current_buff[-for_j+for_i];
}
current_buff=buff_zone[buff_zone_index];
for(for_i=;for_i<buffer_pointer;for_i++)
{
temp_name[for_j+for_i]=current_buff[for_i];
}
}
temp_name[token_length]='\0';
temp_token=malloc(sizeof(struct first_lex_token));
temp_token->token_name=temp_name;
temp_token->current_lex_type=constant;
break;
case ://对应分隔符
temp_name=malloc(sizeof(char)*);
temp_name[]=current_buff[buffer_pointer];
temp_name[]='\0';
buffer_pointer++;
if(buffer_pointer==)
{
buff_zone_index=-buff_zone_index;
current_buff=buff_zone[buff_zone_index];
file_read_byte=fread(current_buff,sizeof(char),,input_file_name);
if(file_read_byte!=)//如果碰到文件的结束了
{
*(current_buff+file_read_byte)=;//标记为文件末尾
//因为我们遇到的是字符文件,所以不会出现17这个字符
}
buffer_pointer=;
}
current_char=current_buff[buffer_pointer];
temp_token=malloc(sizeof(struct first_lex_token));
temp_token->token_name=temp_name;
temp_token->current_lex_type=delimit;
break;
case ://对应字符
token_length=;
buffer_pointer++;
if(buffer_pointer==)
{
buff_zone_index=-buff_zone_index;
current_buff=buff_zone[buff_zone_index];
file_read_byte=fread(current_buff,sizeof(char),,input_file_name);
if(file_read_byte!=)//如果碰到文件的结束了
{
*(current_buff+file_read_byte)=;//标记为文件末尾
//因为我们遇到的是字符文件,所以不会出现17这个字符
}
buffer_pointer=;
}
current_char=current_buff[buffer_pointer];
while(current_char!='\'')
{
token_length++;
buffer_pointer++;
if(buffer_pointer==)
{
buff_zone_index=-buff_zone_index;
current_buff=buff_zone[buff_zone_index];
file_read_byte=fread(current_buff,sizeof(char),,input_file_name);
if(file_read_byte!=)//如果碰到文件的结束了
{
*(current_buff+file_read_byte)=;//标记为文件末尾
//因为我们遇到的是字符文件,所以不会出现17这个字符
}
buffer_pointer=;
}
current_char=current_buff[buffer_pointer];
}
temp_name=malloc(sizeof(char)*(token_length));
if(token_length<=buffer_pointer)
{
for(for_i=;for_i<token_length;for_i++)
{
temp_name[for_i]=current_buff[buffer_pointer-token_length+for_i];
}
}
else
{
current_buff=buff_zone[-buff_zone_index];
for_j=token_length-buffer_pointer;
for(for_i=;for_i<for_j;for_i++)
{
temp_name[for_i]=current_buff[-for_j+for_i];
}
current_buff=buff_zone[buff_zone_index];
for(for_i=;for_i<buffer_pointer;for_i++)
{
temp_name[for_j+for_i]=current_buff[for_i];
}
}
buffer_pointer++;
if(buffer_pointer==)
{
buff_zone_index=-buff_zone_index;
current_buff=buff_zone[buff_zone_index];
file_read_byte=fread(current_buff,sizeof(char),,input_file_name);
if(file_read_byte!=)//如果碰到文件的结束了
{
*(current_buff+file_read_byte)=;//标记为文件末尾
//因为我们遇到的是字符文件,所以不会出现17这个字符
}
buffer_pointer=;
}
temp_name[token_length-]='\0';
if(temp_name[]=='\\')//处理转义字符
{
switch(temp_name[])
{
case 'n':
temp_name[]='\n';
temp_name[]='\0';
break;
case 't':
temp_name[]='\t';
temp_name[]='\0';
break;
case '':
temp_name[]='\0';
break;
case '\\':
temp_name[]='\0';
break;
case '\'':
temp_name[]='\'';
temp_name[]='\0';
break;
case '\"':
temp_name[]='\"';
temp_name[]='\0';
break;
default:
break;
}
}
temp_token=malloc(sizeof(struct first_lex_token));
temp_token->token_name=temp_name;
temp_token->current_lex_type=constant;
break;
case ://代表字符串
token_length=;
buffer_pointer++;
if(buffer_pointer==)
{
buff_zone_index=-buff_zone_index;
current_buff=buff_zone[buff_zone_index];
file_read_byte=fread(current_buff,sizeof(char),,input_file_name);
if(file_read_byte!=)//如果碰到文件的结束了
{
*(current_buff+file_read_byte)=;//标记为文件末尾
//因为我们遇到的是字符文件,所以不会出现17这个字符
}
buffer_pointer=;
}
current_char=current_buff[buffer_pointer];
while()
{
while(current_char!='\"')
{
token_length++;
buffer_pointer++;
if(buffer_pointer==)
{
buff_zone_index=-buff_zone_index;
current_buff=buff_zone[buff_zone_index];
file_read_byte=fread(current_buff,sizeof(char),,input_file_name);
if(file_read_byte!=)//如果碰到文件的结束了
{
*(current_buff+file_read_byte)=;//标记为文件末尾
//因为我们遇到的是字符文件,所以不会出现17这个字符
}
buffer_pointer=;
}
current_char=current_buff[buffer_pointer];
}
if(buffer_pointer==)//判断是否是字符串的结尾
{
if(*(buff_zone[-buff_zone_index]+)!='\\')
{
break;
}
else
{
token_length++;
buffer_pointer++;
//继续下次循环
}
}
else
{
if(current_buff[buffer_pointer-]!='\\')
{
break;
}
else
{
token_length++;
buffer_pointer++;
if(buffer_pointer==)
{
buff_zone_index=-buff_zone_index;
current_buff=buff_zone[buff_zone_index];
file_read_byte=fread(current_buff,sizeof(char),,input_file_name);
if(file_read_byte!=)//如果碰到文件的结束了
{
*(current_buff+file_read_byte)=;//标记为文件末尾
//因为我们遇到的是字符文件,所以不会出现17这个字符
}
buffer_pointer=;
}
current_char=current_buff[buffer_pointer];
}
} }
temp_name=malloc(sizeof(char)*(token_length+));
if(token_length<=buffer_pointer)
{
for(for_i=;for_i<token_length;for_i++)
{
temp_name[for_i]=current_buff[buffer_pointer-token_length+for_i];
}
}
else
{
current_buff=buff_zone[-buff_zone_index];
for_j=token_length-buffer_pointer;
for(for_i=;for_i<for_j;for_i++)
{
temp_name[for_i]=current_buff[-for_j+for_i];
}
current_buff=buff_zone[buff_zone_index];
for(for_i=;for_i<buffer_pointer;for_i++)
{
temp_name[for_j+for_i]=current_buff[for_i];
}
}
temp_name[token_length]='\0';
buffer_pointer++;
temp_token=malloc(sizeof(struct first_lex_token));
temp_token->token_name=temp_name;
temp_token->current_lex_type=string_phrase;
break;
case ://代表操作符
temp_name=malloc(sizeof(char)*);
temp_name[]=current_buff[buffer_pointer];
temp_name[]='\0';
buffer_pointer++;
if(buffer_pointer==)
{
buff_zone_index=-buff_zone_index;
current_buff=buff_zone[buff_zone_index];
file_read_byte=fread(current_buff,sizeof(char),,input_file_name);
if(file_read_byte!=)//如果碰到文件的结束了
{
*(current_buff+file_read_byte)=;//标记为文件末尾
//因为我们遇到的是字符文件,所以不会出现17这个字符
}
buffer_pointer=;
}
temp_token=malloc(sizeof(struct first_lex_token));
temp_token->token_name=temp_name;
temp_token->current_lex_type=an_operator;
break;
default:
printf(" un_recognised type\n");
break;
}
token_chain_node=malloc(sizeof(struct first_token_chain));
token_chain_node->next=NULL;
token_chain_node->current_first_token=temp_token;
if(token_chain_tail==NULL)
{
token_chain_tail=token_chain_node;
token_chain_head=token_chain_node;
}
else
{
token_chain_tail->next=token_chain_node;
token_chain_tail=token_chain_node;
}
seek_return=seek_begin();
}
}

minic 词法单元建立的更多相关文章

  1. Compiler Theory(编译原理)、词法/语法/AST/中间代码优化在Webshell检测上的应用

    catalog . 引论 . 构建一个编译器的相关科学 . 程序设计语言基础 . 一个简单的语法制导翻译器 . 简单表达式的翻译器(源代码示例) . 词法分析 . 生成中间代码 . 词法分析器的实现 ...

  2. minic 类型声明与变量定义句型处理

    #include "token_define.h" //这个文件是用来处理句型的,对于算术表达式都是放在前面的那个头文件中来处理 typedef struct _handle_tr ...

  3. 深入理解javascript作用域系列第二篇——词法作用域和动态作用域

    × 目录 [1]词法 [2]动态 前面的话 大多数时候,我们对作用域产生混乱的主要原因是分不清楚应该按照函数位置的嵌套顺序,还是按照函数的调用顺序进行变量查找.再加上this机制的干扰,使得变量查找极 ...

  4. 【转】深入理解javascript作用域——词法作用域和动态作用域

    前面的话 大多数时候,我们对作用域产生混乱的主要原因是分不清楚应该按照函数位置的嵌套顺序,还是按照函数的调用顺序进行变量查找.再加上this机制的干扰,使得变量查找极易出错.这实际上是由两种作用域工作 ...

  5. JavaScript 词法作用域不完全指北

    在 JavaScript 作用域不完全指北 中,我们介绍了作用域的概念以及 JavaScript 引擎.编译器和作用域的关系.作用域有两种主要的工作模型:词法作用域和动态作用域.其中最为普遍的也是大多 ...

  6. Scala词法文法解析器 (一)解析SparkSQL的BNF文法

    平台公式及翻译后的SparkSQL 平台公式的样子如下所示: if (XX1_m001[D003]="邢おb7肮α䵵薇" || XX1_m001[H003]<"2& ...

  7. 2020 OO 第四单元总结 UML

    title: 2020 OO 第四单元总结 date: 2020-06-14 19:10:06 tags: OO categories: 学习 1. 本单元三次作业的架构设计 本单元的代码编写与第三单 ...

  8. 每周一书《Oracle 12 c PL(SQL)程序设计终极指南》

    本周为大家送出的书是<Oracle 12 c PL(SQL)程序设计终极指南>,此书由机械工业出版社出版, 孙风栋,王澜,郭晓惠 著. 内容简介: <Oracle 12c PL/SQ ...

  9. [译]Python编写虚拟解释器

    使用Python编写虚拟机解释器 一.实验说明 1. 环境登录 无需密码自动登录,系统用户名shiyanlou,密码shiyanlou 2. 环境介绍 本实验环境采用带桌面的Ubuntu Linux环 ...

随机推荐

  1. ASP.NET MVC4+EF5(Lambda/Linq)读取数据

    希望大家记住,这里讲的所有的知识点,不仅仅是了解了就可以了,还要会灵活用,一定要多思考,撑握其中的编程思想. 本文讲的是委托和事件,这两个词可能你早就耳熟能详,但你是否真正撑握了呢? 本系列讲的C#高 ...

  2. 在ns2.35中添加myevalvid框架

    在用ns2进行网络视频通信仿真的时候,先要为我们自己的ns2添加evalvid或者myevalvid框架.其中myevalvid框架是由柯志亨老师整合evalvid和ns2之后得出的新框架,笔者建议大 ...

  3. 【BZOJ 2124】【CodeVS 1283】等差子序列

    http://www.lydsy.com/JudgeOnline/problem.php?id=2124 http://codevs.cn/problem/1283/ 重点是把判断是否存在3个数组成等 ...

  4. C++中的读入输出优化及清新脱俗的宏命令

    C和C++有了#define,从此它就变了模样 宏命令就是#define,#if,#error之类的 本文主要介绍宏命令和相关的骚操作 读入输出优化 inline int read() { int a ...

  5. 【计算几何】【二分】【随机增量法】hdu6167 Missile Interception

    n个半径为R的圆是否有公共部分,等价于询问是否存在一个半径小于R的圆,能覆盖所有n个圆的圆心. 对这n个点求最小圆覆盖即可.从网上扒了个随机增量法的代码. 这样算上二分,复杂度就是nlogn了. #i ...

  6. 【计算几何】【极角排序】Gym - 101174B - Bribing Eve

    把每件物品当成平面上一个点,将第一件物品放在原点.那个权重值相当于一条直线,于是相当于直线绕原点转一圈,统计上侧点的数量. 队友的代码: #include <cmath> #include ...

  7. rust安装

    http://blog.csdn.net/teamlet/article/details/50838996

  8. c bash 代码遍历文件夹下所有文件

    用C代码.bash实现代码遍历文件夹下所有文件 递归方式实现如下: void listdir(char *path) { DIR *ptr_dir; struct dirent *dir_entry; ...

  9. 【java】随机生成6位的数字 /生成例如010 045这样的三位数

    int radomInt = new Random().nextInt(999999) @org.junit.Test public void testName() throws Exception ...

  10. 使用git bash 代替cmd

    上一文章,用Node.js建HTTP服务器,然后在cmd启动,这次尝试用git bash. git bash 也是命令行工具,画面更好看,使用更方便,可以替代cmd. 下载git:https://gi ...