#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. Java之static理解

    说到关键字static,首先想到了常量,静态变量,本文我总结了下static的用法. 1.静态变量 可以被赋值,便于类访问. 2.静态方法 静态方法与静态变量都可以被private.public修饰. ...

  2. NoSQL 数据库应用

      类型 部分代表 特点 列存储 Hbase Cassandra Hypertable 顾名思义,是按列存储数据的.最大的特点是方便存储结构化和半结构化数据,方便做数据压缩,对针对某一列或者某几列的查 ...

  3. Windows 上面优秀的工具软件推荐

    Windows 上面优秀的工具软件推荐 一.下载软件 1.速盘 - 度盘神器 简介: 使百度网盘保持全速下载免受限速困扰! 下载: speedpan 2.http下载工具 百度网盘破解下载器:prox ...

  4. 基于kbengine 0.4.20

    前言: v0.0.1 2015-04-10 誉小痕(shawhen2012@hotmail.com) v0.0.2 2015-04-12 誉小痕(shawhen2012@hotmail.com) ch ...

  5. 关于php的session.serialize_handler的问题

    前言 php的session信息是储存在文件中的 session.save_path="" 指定储存的路径 session.save_handler="" 指定 ...

  6. 2017icpc 乌鲁木齐网络赛

    A .Banana Bananas are the favoured food of monkeys. In the forest, there is a Banana Company that pr ...

  7. Problem G: 十进制数转换为二进制数

    #include<stdio.h> int main() { ]; while(scanf("%d",&n)!=EOF) { ; ) { a[i++]=n%; ...

  8. Problem E: 十六进制转十进制

    #include<stdio.h> int main(void) { ]; int sum,i; while(gets(str)!=NULL) { sum=; ;str[i]!='\0'; ...

  9. [转]jquery后代和子元素的区别

    这是<锋利的jquery>书里的内容 <div>     <p>         <span></span>         <a&g ...

  10. 兼容IE8

    由于IE8不支持HTML5,而它又是Win7的默认浏览器,我们即使讨厌它,在这几年却也拿它没办法. 最近做了个需要兼容IE8的项目,不可避免地用了HTML5+CSS3,甚至canvas和svg,做兼容 ...