当前位置:作文大全 > 编译原理词法分析器实践报告 词法分析器c语言

编译原理词法分析器实践报告 词法分析器c语言

时间:2021-10-26 17:01:51 浏览次数:

 . . .

 .. ..

 理工大学

 软件学院

 《编译原理》

 项目实践报告

 题 目

 :词法分析器

 班 级

 :软件15-4班

 专 业

 :软件工程

 :吕小胜

 :

 学号

 :1514010414

 :

 指导教师

 :春祥

 日期

 :2017年4月19日

 目录

 TOC \o "1-2" \h \u 1611 一、需求分析 2

  5674 二、系统设计 2

  28396 (一)系统中的数据定义 2

  32696 (二)系统的概要设计 3

  8077 (三)系统的详细设计 3

  7952 (四)系统的核心算法 4

  17008 三、系统编码及运行 5

  30155 (一)系统开发涉及的软件 5

  14778 (二)系统运行界面及结果 5

  28830 四、系统测试 5

  11724 五、总结 5

  21217 附录(源代码) 5

 一、需求分析

 词法分析(Lexical Analysis) 是编译的第一阶段。词法分析器的主要任务是读入源程序的输入字符、将他们组成词素,生成并输出一个词法单元序列,每个词法单元对应一个词素。这个词法单元序列被输出到语法分析器进行语法分析。

 二、系统设计

 (一)系统中的数据定义

 本词法分析器演示的是C语言的一个子集,故字符集如下:

 (1)标识符:以字母开头的字母数字串。

 (2)常熟

 (3)保留字:auto, break, case, char, const, continue, default, do, double, else, enum, extern, float, for, goto, if, int, long, register, return, short, signed, sizeof, static, struct, switch, typedef, union, unsigned, void, volatile, while

 (4)运算符:+、-、*、/、%、>、<、=、!=、==、<=、>=、++、--、!、

 &、&&、||;

 界符:[ ] { } ( ) : ‘’ “” # ,

 单词

 分类号

 标识符

 1

 常数

 2

 保留字

 3

 界符

 4

 运算符

 5

 单词分类表

 (二)系统的概要设计

 (三)系统的详细设计

  1、TestLexer()

 void writeFile(String str1,StringBuilder number)

 boolean isDigit(char ch)

 boolean isLetter(char ch)

 boolean isKeyWord(StringBuilder str)

 boolean isOperator(char ch)

 boolean isSeparators(char ch)

  (四)系统的核心算法

 TestLexer()

 程序入口

 StringBuffer buffer;

 文件读入缓冲区

 Char[] cs;

 字符变量,存放源程序字符

 StringBuilder sb;

 字符串,存放切割出的字词

 boolean isLetter(char ch)

 判断ch是否为字母

 boolean isDigit(char ch)

 判断是否为数字

 boolean isKeyWord(String)

 判断是否为关键字

 boolean isOperator(char)

 判断是否为运算符

 boolean isSeparators(char)

 判断是否为分隔符

 void writeFile(String str1,StringBuilder number)

 按照二元式规则写入文件

 三、系统编码及运行

 (一)系统开发涉及的软件

 WPS文字、eclipse、

 系统运行界面及结果

 

 系统测试

 五、总结

  通过此次实验,让我了解到如何设计、编制并调试词法分析程序,熟悉了构造 词法分析程序的手工方式的相关原理,加深了对编译原理词法分析的理解,本次使用java语言直接编写此法分析程序,也让我重新熟悉了java语言的相关容,加深了对java语言的用途的理解。本程序的数据输入采取直接从文件中读取,

 而不是由键盘输入,因此在测试过程中,输入得到大大简化,但是本程序的关键字表只初始化了一部分关键字,还可继续扩充(只需扩大数组,向其中补充要添加的关键字),而且程序的测试数据存在不足,程序可能存在未发现的漏洞,以上两点有待改善。

 附录

 import java.io.File;

 import java.io.FileReader;

 import java.io.FileWriter;

 import java.io.IOException;

 import java.io.InputStream;

 public class TestLexer {

  // 保留字集

  static String[] keyWords = { "auto", "break", "case", "char", "const",

  "continue", "default", "do", "double", "else", "enum", "extern",

  "float", "for", "goto", "if", "int", "long", "register", "return",

  "short", "signed", "sizeof", "static", "struct", "switch",

  "typedef", "union", "unsigned", "void", "volatile", "while" };

  // 运算符集

  static char[] operators = {'+','-','*','/','%','=','<','>','!','&','|'};

 

  // 界符集

  static char[] Separators = { '[', ']', '{', '}', '(', ')', ':', '\'', '"',

  '#', ';' };

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

  // 读取文件

  File f = new File("d:/aa.txt");

  FileReader r = new FileReader(f);

  char[] cs = new char[(int) f.length()];

  int length = r.read(cs);

  System.out.println(cs);

  System.out.println("");

  int flag = 0;

  StringBuilder sb = new StringBuilder();

  for (int i = 0; i < cs.length; i++) {

  // 如果是字母

  if (isLetter(cs[i])) {

  if(cs[i+1] != ' ' && !isDigit(cs[i+1]) && !isOperator(cs[i+1]) && !isSeparator(cs[i+1]) && !isOperator(cs[i+1])){ //如果后一个字符不是空格

  sb.append(cs[i]);

  continue;

  }else{

  sb.append(cs[i]);

  if(isKeyWord(sb)){

  writeFile("3", sb);

  sb = new StringBuilder();

  }else{

  writeFile("1", sb);

  sb = new StringBuilder();

  }

  continue;

  }

  } else {

  // 如果是数字

  if (isDigit(cs[i])) {

  if (isDigit(cs[i + 1])) {// 如果前后都是数字的话

  sb.append(cs[i]);

  continue;

  } else {

  sb.append(cs[i]);

  writeFile("2", sb);

  sb = new StringBuilder();

  continue;

  }

  }

  // 如果是界符

  if (isSeparator(cs[i])) {

  sb.append(cs[i]);

  writeFile("4", sb);

  sb = new StringBuilder();

  continue;

  }

  // 如果是运算符

  if (isOperator(cs[i])) {

  if(isOperator(cs[i+1])){

  sb.append(cs[i]);

  continue;

  } else{

  sb.append(cs[i]);

  writeFile("5", sb);

  sb = new StringBuilder();

  continue;

  }

  }

  }

  }

  }

  // 判断是否为数字

  public static boolean isDigit(char ch) {

  boolean result = false;

  if (ch <= 57 && ch >= 48) {

  result = true;

  }

  return result;

  }

  // 判断是否为字母

  public static boolean isLetter(char ch) {

  boolean result = false;

  if ((ch >= 65 && ch <= 90) || (ch >= 97 && ch <= 122)) {

  result = true;

  }

  return result;

  }

  // 判断是否为关键字

  public static boolean isKeyWord(StringBuilder str) {

  boolean result = false;

  String str1 = new String(str);

  for(int i = 0; i < keyWords.length; i++){

  if(keyWords[i].endsWith(str1)){

  result = true;

  }

  }

  return result;

  }

  // 判断是否为运算符

  public static boolean isOperator(char ch) {

  boolean result = false;

  for(int i = 0; i < operators.length; i++){

  if(operators[i] == ch){

  result = true;

  }

  }

  return result;

  }

 

  // 判断是否为界符

  public static boolean isSeparator(char ch) {

  boolean result = false;

  for (int i = 0; i < Separators.length; i++) {

  if (Separators[i] == ch) {

  result = true;

  }

  }

  return result;

  }

  // 按照二元式规则写入文件

  public static void writeFile(String str1, StringBuilder number)

  throws IOException {

  String str = number + "\t" + "(" + str1 + "," + number + ")";

  if (str1.endsWith("1")) {

  str = str + "\t" + "\t" + "标识符";

  }

  if (str1.endsWith("2")) {

  str = str + "\t" + "\t" + "常数";

  }

  if (str1.endsWith("3")) {

  str = str + "\t" + "\t" + "保留字";

  }

  if (str1.endsWith("4")) {

  str = str + "\t" + "\t" + "界符";

  }

  if (str1.endsWith("5")) {

  str = str + "\t" + "\t" + "运算符";

  }

  File file = new File("d:/aaa.txt");

  FileWriter w = new FileWriter(file, true);

  w.write(str + "\r\n");

  w.close();

  }

 }