编译原理 词法分析器简单实现 java代码
2019-05-08 21:35
429 查看
词法分析(英语:lexical analysis)是计算机科学中将字符序列转换为单词(Token)序列的过程。进行词法分析的程序或者函数叫作词法分析器(Lexical analyzer,简称Lexer),也叫扫描器(Scanner)。词法分析器一般以函数的形式存在,供语法分析器调用。 完成词法分析任务的程序称为词法分析程序或词法分析器或扫描器。
实验目的
通过本实验使学生进一步熟悉和掌握程序设计语言的词法分析程序的设计原理及相关的设计技术,如何针对确定的有限状态自动机进行编程序;熟悉和掌握程序设计语言的语法分析程序的设计原理、熟悉和掌握算符优先分析方法。
实验要求
本实验要求:①要求能熟练使用程序设计语言编程;②在上机之前要有详细的设计报告(预习报告);③要编写出完成相应任务的程序并在计算机上准确地运行;④实验结束后要写出上机实验报告。
实验题目
针对下面文法G(S):
S→ v = E
E→E+E│E-E│E*E│E/E│(E)│ v │ i
其中,v为标识符,i为整型或实型数。要求完成
① 使用自动机技术实现一个词法分析程序;
② 使用算符优先分析方法实现其语法分析程序,在语法分析过程中同时完成常量表达式的计算。
构建DFA
java代码
结合注释和DFA的图看就好了
package lab1; import java.util.*; /* 编号规定: 001:加法运算符 002:减法运算符 003:乘法运算符 004:除法运算符 005:左括号 013:右括号 008.标识符 010.整数 011.等号运算符 012.浮点数 014:错误字段 */ public class lexicalAnalysis { private static char[] Code;//转化为字符数组 public static ArrayList<String> tokens=new ArrayList<>();//用于之后的语法分析传值使用 public static void main(String[] args) { // String s = "abc2@e=num2+12.3.23)*123-12.#";//输入符号串 String s = "A1=1.2+3*(4-6/3)#";//表达式为A1=1.2+3*(4-6/3) StartLexicalAnalysis(s); } public static void StartLexicalAnalysis(String s) {//开始进行语法分析 if (IsCode(s)) {//判断 System.out.println("当前输入符号为:" + s.substring(0,s.length()-1)); System.out.println("词法分析结果如下:"); StartState(0, 0); } } private static boolean IsCode(String s){//判断源代码是否为空,为空则不能进行词法分析 if (s.isEmpty()||s.toCharArray()[0]=='#') { System.out.println("源代码为空,无法进行词法分析!"); return false; } else { Code = s.toCharArray(); return true; } } private static void StartState(int basicPointer, int currentPointer)//状态0,初始状态 { if (Code[currentPointer] == '#') { System.out.println("词法分析结束"); } else if (IsEqual(Code[currentPointer]))//如果当前字符是等于号进入EqualState { EqualState(currentPointer); } else if (IsAdd(Code[currentPointer]))//如果当前字符是加号进入AddState { AddState(currentPointer); } else if (IsSub(Code[currentPointer]))//如果当前字符是减号进入SubState { SubState(currentPointer); } else if (IsMul(Code[currentPointer]))//如果当前字符是乘号进入MulState { MulState(currentPointer); } else if (IsDiv(Code[currentPointer]))//如果当前字符是除号进入DivState { DivState(currentPointer); } else if (IsLParent(Code[currentPointer]))//如果当前字符是左括号进入LParentState { LParentState(currentPointer); } else if (IsRParent(Code[currentPointer]))//如果当前字符是右括号进入RParentState { RParentState(currentPointer); } else if (IsAlpha(Code[currentPointer]))//如果当前字符是字母号进入IdentState { IdentState(basicPointer, currentPointer + 1);//是字母就进入状态6 } else if (IsDigit(Code[currentPointer]))//如果当前字符是数字进入IntState { IntState(basicPointer, currentPointer + 1);//是数字就进入状态7 } else { System.out.println("(014,错误," + Code[currentPointer] + ")"); String tempSt="014,"+Code[currentPointer]; tokens.add(tempSt); StartState(basicPointer + 1, currentPointer + 1); } } private static void EqualState(int j)//表示字符为等号运算符 { System.out.println("(011,等于号," + Code[j] + ")"); String tempSt="011,"+Code[j]; tokens.add(tempSt); StartState(j + 1, j + 1); } private static void AddState(int j)//表示字符为加法运算符 { System.out.println("(001,加号," + Code[j] + ")"); String tempSt="001,"+Code[j]; tokens.add(tempSt); StartState(j + 1, j + 1); } private static void SubState(int j)//表示字符为减法运算符 { System.out.println("(002,减号," + Code[j] + ")"); String tempSt="002,"+Code[j]; tokens.add(tempSt); StartState(j + 1, j + 1); } private static void MulState(int j)//表示字符为乘法运算符 { System.out.println("(003,乘号," + Code[j] + ")"); String tempSt="003,"+Code[j]; tokens.add(tempSt); StartState(j + 1, j + 1); } private static void DivState(int j)//表示字符为除法运算符 { System.out.println("(004,除号," + Code[j] + ")"); String tempSt="004,"+Code[j]; tokens.add(tempSt); StartState(j + 1, j + 1); } private static void LParentState(int j)//字符为左括号 { System.out.println("(005,左括号," + Code[j] + ")"); String tempSt="005,"+Code[j]; tokens.add(tempSt); StartState(j + 1, j + 1); } private static void RParentState(int j)//字符为右括号 { System.out.println("(0013,右括号," + Code[j] + ")"); String tempSt="013,"+Code[j]; tokens.add(tempSt); StartState(j + 1, j + 1); } private static void IdentState(int i, int j)//标识符 { //Code[i]为准标识符的第一个字符,是个字母 ,而Code[j-1]是字母或数字 if (IsDigit(Code[j]) || IsAlpha(Code[j])) //如果当前字符仍然为字母或数字则再次进入IdentState { IdentState(i, j + 1); } else//如果当前字符为非数字及字母字符,则表明Code[i]~Code[j-1]这一段是标识符 { System.out.print("(008,标识符,"); String tempSt="008,"; printA(i, j, tempSt); } } private static void IntState(int i, int j)//状态7,准实数 { //Code[i]为准实数的第一个字符,是个字母 ,而Code[j-1]是数字或小数点 if (IsDigit(Code[j]))//如果当前字符仍然是数字,则再次进入IntState { IntState(i, j + 1); } if (Code[j] == '.')//如果当前字符是小数点,进入PointState { PointState(i, j + 1); } if ((Code[j] != '.') && !IsDigit(Code[j])) //如果当前字符既不为小数点也不是数字 ,则表明Code[i]~Code[j-1]这一段是个实数 { System.out.print("(010,整数,"); String tempSt="010,"; printA(i, j, tempSt); } } private static void PointState(int i, int j)//整数后接个小数点的中间态 { //Code[i]~Code[j-1]之中含有小数点 if (!IsDigit(Code[j])) {//小数点后还是小数点或者不是数字时报错 System.out.print("(014,错误,"); String tempSt="014,"; int q = i;//从Code[i]开始算起 while ((IsDigit(Code[q])) || (Code[q]) == '.') //直接相连的数字或小数点都属于这个无效字段的一部分 { tempSt=tempSt+Code[q]; System.out.print(Code[q]); q++; } System.out.println(")"); tokens.add(tempSt); //Code[q]此时为无效字段的下一个字符 StartState(q, q); } if (IsDigit(Code[j]))//如果当前字符是数字,则进入FloatState { FloatState(i, j + 1); } } private static void FloatState(int i,int j){ if (IsDigit(Code[j]))//如果当前字符是数字,则再次进入FloatState { FloatState(i, j + 1); } if (!IsDigit(Code[j])) //如果当前字符是非数字字符,说明Code[i]~Code[j-1]这一段是浮点数 { System.out.print("(012,浮点数,"); String tempSt="012,"; printA(i, j, tempSt); } } private static void printA(int i, int j, String tempSt) {//用于输出非单一字符 for (int k = i; k < j; k++) { tempSt = tempSt + Code[k]; System.out.print(Code[k]); } System.out.println(")"); tokens.add(tempSt); StartState(j, j); } private static boolean IsEqual(char ch) {//判断是否是字符'=' return ch == '='; } private static boolean IsAdd(char ch)//判断是否是字符'+' { return ch == '+'; } private static boolean IsSub(char ch)//判断是否是字符'-' { return ch == '-'; } private static boolean IsMul(char ch)//判断是否是字符'*' { return ch == '*'; } private static boolean IsDiv(char ch)//判断是否是字符'/' { return ch == '/'; } private static boolean IsLParent(char ch)//判断是否左括号 { return ch == '('; } private static boolean IsRParent(char ch)//判断是否是有括号 { return ch == ')'; } private static boolean IsDigit(char ch) {//判断是否是数字 return Character.isDigit(ch); } private static boolean IsAlpha(char ch) {//判断是否是字母 return Character.isLetter(ch); } }
运行结果
相关文章推荐
- Java 队列实现原理及简单实现代码
- 利用Java实现简单的词法分析器实例代码
- Java 实现词法分析器(编译原理)
- 一个简单词法分析器的实现代码(java实现)
- 一个简单词法分析器的实现代码(java实现)
- 深入浅出编译原理-4-一个简单词法分析器的C语言实现
- Java中2.5D游戏的设计与实现(3)—八方走法实现原理及相关代码
- 分页技术原理与实现(二)——Java+Oracle代码实现
- 排序与查找简单算法 java代码实现
- java基于TCP的socket编程简单实现[代码实践过]
- Java NIO原理 图文分析及代码实现
- Kruskal生成树算法的java代码简单实现
- Java NIO原理图文分析及代码实现
- 分页技术原理与实现(二)——Java+Oracle代码实现
- 深入浅出编译原理-5-一个简单语法分析器的C语言实现
- 最简单的Java I/O实现-3行代码实现
- 第一次动手写java的简单代码,实现输出一个空心菱形。
- 利用java代码实现java源文件的编译和打包为jar文件
- java中list数据拆分为sublist实现分页的简单代码
- Java NIO原理 图文分析及代码实现