资源下载地址:https://download.csdn.net/download/sheziqiong/86873815
资源下载地址:https://download.csdn.net/download/sheziqiong/86873815
词法分析程序实验:
提交源程序和可运行程序。
来源:同学在作业连接下分享的文件

关键字包括:(小写)
or, and , int, bool, char, while, do, true, false
if, then, else, end, repeat, until, read, write
操作符包括:
>, <=, >=, <, =
,, ', {, }, ;, :=
(,), +, -, *, /
空格符包括: , \t, \n,在词法分析后不被保留。
其他符号有四种,他们的正则定义如下:
ID:letter(letter|digit)*NUM:digit digit*STRING:'any char except ' '(不能跨行定义){...}(用花括号标注,可以跨行定义)Windows下运行
gcc la.c -o la.exe
a.exe
测试文件位于\test文件夹
程序中定义的 TOKEN 类型
// Keyword tokens // |-18 Keywords-----------|
KEY_OR, KEY_AND, KEY_NOT, // | or | and | not |
KEY_INT, KEY_BOOL, KEY_CHAR, // | int | bool | char |
KEY_WHILE, KEY_DO, // | while | do | |
KEY_IF, KEY_THEN, KEY_ELSE, // | if | then | else |
KEY_END, KEY_REPEAT, KEY_UNTIL, // | end | repeat| until |
KEY_READ, KEY_WRITE, // | read | write | |
KEY_TRUE, KEY_FALSE, // | true | false | |
// Operator tokens // |-17 Operators-|
OP_G, OP_L, OP_ASSIGN, // | > | < | := |
OP_GE, OP_LE, OP_EQ, // | >= | <= | = |
OP_COMMA, OP_QUOTA, OP_SEMI, // | , | ' | ; |
OP_LPAREN, OP_RPAREN, // | ( | ) | |
OP_LBRACE, OP_RBRACE, // | { | } | |
OP_ADD, OP_SUB, // | + | - | |
OP_MUL, OP_DIV, // | * | / | |
// Other tokens // |-Each NF--------------------|-Example-|
ID, // | letter(letter|digit)* | c1 |
NUM, // | digit digit* | 123 |
STRING, // | ' any character except' ' | 'hi!' |
NONE, // | | 1c |
ANNO // | { any character } | {hi} |
};
并提供相关函数获取TOKEN_TYPE,其字符串形式
char* getTokenName(enum TOKEN_TYPE i);
enum TOKEN_TYPE getTokenType(char *token);
以下是词法分析有关数据结构
typedef struct TOKEN{ // TOKEN 二元组
enum TOKEN_TYPE type; // 词素
char info[SIZE_2]; // 含义
}TOKEN;
FILE* file; // 待分析文件的指针
TOKEN file_tokens[SIZE_1]; // 保存词法分析结果
int file_tokens_num; // 分析的TOKEN总数
int current_row; // 当前扫描位置(行数)
int current_col; // 当前扫描位置(列数)
char current_word[SIZE_2]; // 当前扫描得到的单词
int current_word_ptr; // 当前扫描单词的长度
enum TOKEN_TYPE current_type; // 当前的预测TOKEN类型
int operator_flag = 0; // 操作符标记
int error; // 词法分析错误处
/**
* 初始化:为所有用到的变量(@line 136- 147)赋初始值,若文件无啊打开,提示报错。
* @param file_path
* @return 1 if the file is opened successfully, otherwise 0.
*/
int la_initial(char file_path[]);
/**
* 根据当前的 current_word 和 current_type 生成 Tokens 并保存在 file_tokens 中。
*/
void la_make_token();
/**
* 输出词法编译结果:显示出错原因和出错位置(几行几列)
* @param message 出错信息
* @param row 出错位置(行数)
* @param col 出错位置(列数)
*/
void la_show_error(const char* message, int row, int col);
/**
* 在扫描新的一行时进行预处理
*/
void la_update_line();
/**
* 根据下一个字符 c 来更新 current_word 和 current_type。
* @param c lookahead symbol
*/
void la_update_word(char c);
/**
* 词法分析入口:执行文件字符扫描和词法分析,在出现错误时或读完程序时终止
*/
void la_start();
用户可以输入文件地址,每次输入一个文件路径,程序读取文件内容并作语法分析,将词法分析结果直接输出。
核心部分代码:
if(la_initial(file_path)){ // 1、初始化,若成功则进入词法分析
la_start(); // 2、执行词法分析
if(error == 0) // 3、若没有错误出现
la_show_result(); // 4、则输出TOKEN序列
}
测试一段普通的TINY+程序的词法分析结果
char str;
int x, fact;
str:= 'sample program in TINY+ language';
read x;
if x > 0 and x < 100 then { don't do it }
fact:=1;
while x > 0 do
fact:=fact*x;
x:=x-1
write fact
end
测试结果:如下图所示。


{cc'oo'o}、'cco{}coc'true false or and not
int bool char while do
if then else end repeat
until read write , ;
:= + - * /
( ) < = >
<= >= a2c 123 'EFG'
{cc'oo'o} cco0 'cco{}coc'

测试内容:测试击中错误代码,分别保存在t3.txt,t4.txt,t5.txt,t6.txt中。
$ hello
123hello
hello'
hello}
它们分别代表:非法字符输入、非法ID、字符串不完整、注释不完整。
测试结果:

资源下载地址:https://download.csdn.net/download/sheziqiong/86873815
资源下载地址:https://download.csdn.net/download/sheziqiong/86873815