词法分析器

更新时间:2023-09-25 16:27:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

词法分析器

一、实验目的:

1.能够采用C编程语言实现简单的词法分析程序;

2.设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。 二、实验要求:

1.对单词的构词规则有明确的定义;

2.编写的分析程序能够正确识别源程序中的单词符号; 3.识别出的单词以<单词类型,单词本身,行号,列号>的形式保存在符号表中(链表);

4.词法分析中源程序的输入以.c格式,分析后的符号表,将四元组保存在output.txt文件中。 三、实验内容:

选择高级语言(C语言),编制它的词法分析程序。词法分析程序的实现可以采用任何一种编程工具。 四、实验原理:

1.算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号;

2.其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。

五、实验分析:

5.1 待分析的简单的词法 (1)关键字:

begin if then while do end所有的关键字都是小写。 (2)运算符和界符

:= + - * / < <= <> > >= = ; ( ) #

(3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义: ID = letter (letter | digit)* NUM = digit digit*

(4)空格有空白、制表符和换行符组成。空格一般用来分隔ID、SUM、运算符、界符和关键字,词法分析阶段注释通常被忽略。

5.2各种单词符号对应的种别码:

表5.2各种单词符号对应的种别码

单词符号 种别码 单词符号 种别码 bgin 1 : 17 If 2 := 18 then 3 < 20 while 4 <> 21 do 5 <= 22 end 6 > 23 lettet10 >= 24 (letter|digit)* dight dight* 11 = 25 + 13 ; 26 - 14 ( 27 * 15 ) 28 / 16 # 0 5.3 词法分析程序的功能: 输入:所给文法的源程序input.txt文本文档。

输出:四元组(type,name,rows,cols)构成的output.txt文本文档。

其中:type为单词种别码; name为单词名称; rows为所在文件行号;

cols为所在文件列号。

例如:对源程序begin x:=9: if x>9 then x:=2*x+1/3; end #的源文件,经过词法分析后输出如下序列:

(1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)??

词法分析状态转换图(终结状态右上角*表示多读一个符号) 空格/换行0#1字母/数字字母2数字数字4非数字5*数字非字母数字3*标识符(需进一步判断是否为关键字)#,结束+6非==78*++=*-9非==1011--=...()1213()

六、词法分析程序的算法思想:

算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。

6.1 主程序示意图:

主程序示意图如图6-1所示。其中初始包括以下两个方面: ⑴ 关键字表的初值。

关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。如能查到匹配的单词,则该单词为关键字,否则为一般标识符。关键字表为一个字符串数组,其描述如下:

Char *rwtab[6] = {“begin”, “if”, “then”, “while”, “do”, “end”};

置初值 调用扫描子程序 输出单词四元组 输入串结束 是 结束 图3-1 (2)程序中需要用到的主要变量为syn,token和sum 6.2 扫描子程序的算法思想:

首先设置3个变量:①token用来存放构成单词符号的字符串;②sum用来存放整型单词;③syn用来存放单词符号的种别码。扫描子程序主要部分流程如图3-2所示。

图 3-2

七、实验环境:

需要TC、VC++ 6.0等开发工具作为本次试验的环境。 八、实验步鄹:

1、准备: 用TC、VC++等开发工具;

2、对本实验的任务进行分析,确定实现功能的函数; 3、写好程序,仔细修改函数;

4、上机操作:输入源程序,修改、调试,运行。 5、写好试验报告。

九、词法分析程序的C++语言程序源代码: package com.mr.main;

import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWriter; import java.util.HashMap; import java.util.Map;

public class AnalysisTestPro {

private static Map map = new HashMap();

private static String inFilePath = \输入的文件路径

private static String outFilePath = \输出的文件的路径

private static BufferedWriter bw;

public static void main(String[] args) throws Exception { addKeyCharacterToMap();

BufferedReader br = new BufferedReader(new FileReader(inFilePath));

bw = new BufferedWriter(new FileWriter(outFilePath));

String codes = \ int line = 0;//行数

String str = \单词\\t类型\\t行数\\t列数\ System.out.println(str); bw.write(str);

while ((codes = br.readLine()) != null) { line++;

analysis(codes,line); }

br.close(); bw.flush(); bw.close(); }

//词法分析算法

private static void analysis(String codes,int line) throws Exception{

String key = \代表一个关键字或者一串变量名

for (int i = 0; i < codes.length(); i++) { char ch = codes.charAt(i); //判断关键字如:begin if ( ch != ' ' &&(

(((ch <= 'z') && (ch >= 'a')) || ((ch <= 'Z') && (ch >= 'A')))|| ((!\

key.substring(0,1).matches(\

(ch>='0' &&ch<='9' || !(ch+\\\\\*\\\\/\\\\>\\\\<\\\\!\\\\;\\\\#\\\\{\\\\}\\\\(\\\\)]\ ) {

key += ch; //后续单词 } else {

if (map.get(key) != null) {

output(key, key, line, i-key.length()+1); } else {

if (!\

output(key, \ } }

key = \ }

// 数字

if (ch >= '0' && ch <= '9' && !(!\

key.substring(0,1).matches(\ key += ch; while(true) {

if(i+1 < codes.length()) {

String nextCh = codes.charAt(i +1) + \ if(nextCh.matches(\

&& !key.matches(\][\\\\s\\\\S]*\

key += nextCh; i++; } else {

if(key.matches(\{

output(key.substring(0,key.length()-1),\

output( key.substring(key.length()-1), key.substring(key.length()-1),line, i+1); } else {

output( key, \ }

key = \ break; }

} else {

if(key.matches(\ output(key.substring(0,key.length()-1),\

output( key.substring(key.length()-1), key.substring(key.length()-1),line, i+1); } else {

output( key, \ }

key = \ break; } } }

// 符号

if (map.get(ch + \ // ?处理特殊的符号如:=,<>,>=

if (ch == '!' || ch == '<' || ch == '>' || ch=='/' || ch=='=') {

if (i + 1 < codes.length()) {

char nextCh = codes.charAt(i + 1); String str = \ if (map.get(str) != null) { output(str, str,line, i + 1); i++;

}else if(str.equals(\ return; } else {

output(\ }

} else {

output(\ }

} else {

output(\ } } }

if(!\

output(key, \ } }

//写到文件里

private static void output(String character, String key,int line, int i) throws Exception {

String pwStr = \+line+\

System.out.println(pwStr); bw.write(pwStr+\ }

// 初始化关键字到hashmap里,以便查找到对应的种别码 static void addKeyCharacterToMap() {

String[] character = { \\

\ \ for (int i = 0; i < character.length; i++) { String value = \ if (i <= 6) {

value = \关键字\ } else if(i == 7){

value=\标识符\ } else if(i==8){ value=\数字\

} else if(i>8 && i<20){ value=\操作符\ } else {

value=\分隔符\ }

map.put(character[i], value); } } }

十、结果分析:

输入文件内容:input.txt double a=5.4e-10 while(true){//注释 a++; break; }

int x=9; if(x>9){ x=x*2+1; }

输出文件内容:output.txt 单词 类型 行数列数 (double 标识符1 1) (a 标识符 1 8) (= 操作符 1 9)

(5.4e-10 数字1 16) (while 关键字2 1) (( 分隔符 2 6) (true 标识符 2 7) () 分隔符 2 11) ({ 分隔符 2 12) (a 标识符 3 5) (+ 操作符 3 6) (+ 操作符 3 7) (; 分隔符 3 8) (break 标识符4 5)

(; 分隔符 4 10) (} 分隔符 5 1) (int 关键字 6 1) (x 标识符 6 5) (= 操作符 6 6) (9 数字 6 7) (; 分隔符 6 8) (if 关键字 7 1) (( 分隔符 7 3) (x 标识符 7 4) (> 操作符 7 5) (9 数字 7 6) () 分隔符 7 7) ({ 分隔符 7 8) (x 标识符 8 5) (= 操作符 8 6) (x 标识符 8 7) (* 操作符 8 8) (2 数字 8 9) (+ 操作符 8 10) (1 数字 8 11) (; 分隔符 8 12) (} 分隔符 9 1) 十一、总结:

词法分析的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。通过本试验的完成,更加加深了对词法分析原理的理解。

本文来源:https://www.bwwdw.com/article/5tnd.html

Top