实现词法分析器
实验内容要求
一、实验目的 加深对词法分析器的工作过程的理解;加强对词法分析方法的掌握;能够采用一种编程 语言实现简单的词法分析程序;能够使用自己编写的分析程序对简单的程序段进行词法分 析。
二、实验内容 自定义一种程序设计语言,或者选择已有的一种高级语言,编制它的词法分析程序。词 法分析程序的实现可以采用任何一种编程语言和编程工具。 从输入的源程序中,识别出各个具有独立意义的单词,即关键字、标识符、常数、运算 符、界符。并依次输出各个单词的内部编码及单词符号自身值。(遇到错误时可显示“Error”, 然后跳过错误部分继续显示)
三、实验要求: 1. 对单词的构词规则有明确的定义; 2. 编写的分析程序能够正确识别源程序中的单词符号; 3. 识别出的单词以<种别码,值>的形式保存在符号表中,正确设计和维护符号表; 4. 对于源程序中的词法错误,能够做出简单的错误处理,给出简单的错误提示,保 证顺利完成整个源程序的词法分析;
四、实验步骤 1. 定义目标语言的可用符号表和构词规则; 2. 依次读入源程序符号,对源程序进行单词切分和识别,直到源程序结束; 3. 对正确的单词,按照它的种别以<种别码,值>的形式保存在符号表中; 4. 对不正确的单词,做出错误处理。
实验方法
根据对应的状态转换图完成编码就可以了,内容我不详细多说,下面的图可以作为参照,实际上还需要自己去思考更多,我的代码还是存在一点小问题的,仅供大家参考。

import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;public class LexicalAnalyzer {/** 1表示关键字* 2表示标识符* 3表示常数* 4表示运算符* 5表示界符* 6表示字符串* *///关键字static String []keyWord={"private","protected","public","abstract","class","extends","final","implements","interface","native","new","static","strictfp","break","continue","return","do","while","if","else","for","instanceof","switch","case","default","boolean","byte","char","double","float","int","long","short","String","null","true","false","void","this","goto"};//运算符static String []operation={"+","-","*","/","%","++","--","-=","*=","/=","&","|","^","~","<<",">>",">>>","==","!=",">","<","=",">=","<=","&&","||","!","."};//界符static String []symbol={",",";",":","(",")","{","}"};static ArrayList<String> keyWords=null;static ArrayList<String> operations=null;static ArrayList<String> symbols=null;//指向当前所读到字符串的位置的指针static int p,lines;public static void main(String []args) throws FileNotFoundException {init();File file=new File("E:\\code\\bytest\\test11\\test2.txt");lines=1;try(Scanner input=new Scanner(file)) {while (input.hasNextLine()){String str=input.nextLine();analyze(str);lines++;}}}//初始化把数组转换为ArrayListpublic static void init(){keyWords=new ArrayList<>();operations=new ArrayList<>();symbols=new ArrayList<>();Collections.addAll(keyWords, keyWord);Collections.addAll(operations, operation);Collections.addAll(symbols, symbol);}public static void analyze(String str){p=0;char ch;str=str.trim();for (;p<str.length();p++){ch=str.charAt(p);if (Character.isDigit(ch)){digitCheck(str);}else if (Character.isLetter(ch)||ch=='_'){letterCheck(str);}else if (ch=='"'){stringCheck(str);}else if (ch==' '){continue;}else {symbolCheck(str);}}}/*数字的识别* 1、识别退出:* 1.1、遇到空格符* 1.2、遇到运算符或者界符* 2、错误情况:* 2.1、两个及以上小数点* 2.2、掺杂字母* */public static void digitCheck(String str){String token= String.valueOf(str.charAt(p++));//判断数字的小数点是否有且是否大于1int flag=0;boolean err=false;char ch;for (;p<str.length();p++) {ch = str.charAt(p);if (ch==' '||(!Character.isLetterOrDigit(ch)&&ch!='.')) {break;}else if (err){token+=ch;}else {token+=ch;if (ch == '.') {if (flag == 1) {err = true;} else {flag++;}}else if (Character.isLetter(ch)){err=true;}}}if (token.charAt(token.length()-1)=='.'){err=true;}if (err){System.out.println(lines+"line"+": "+token+" is wrong");}else {System.out.println("("+3+","+token+")");}if (p!=str.length()-1||(p==str.length()-1&&!Character.isDigit(str.charAt(p)))){p--;}}//标识符,关键字的识别public static void letterCheck(String str){String token= String.valueOf(str.charAt(p++));char ch;for (;p<str.length();p++){ch=str.charAt(p);if (!Character.isLetterOrDigit(ch)&&ch!='_'){break;}else{token+=ch;}}if (keyWords.contains(token)){System.out.println("("+1+","+token+")");}else {System.out.println("("+2+","+token+")");}if (p!=str.length()-1||(p==str.length()-1&&(!Character.isLetterOrDigit(str.charAt(p))&&str.charAt(p)!='_'))){p--;}}//符号的识别public static void symbolCheck(String str){String token= String.valueOf(str.charAt(p++));char ch;if (symbols.contains(token)){System.out.println("("+5+","+token+")");p--;}else {if (operations.contains(token)){if (p<str.length()){ch=str.charAt(p);if (operations.contains(token+ch)){token+=ch;p++;if (p<str.length()){ch=str.charAt(p);if (operations.contains(token+ch)){token+=ch;System.out.println("("+4+","+token+")");}else{p--;System.out.println("("+4+","+token+")");}}else{System.out.println("("+4+","+token+")");}}else {p--;System.out.println("("+4+","+token+")");}}}else {p--;System.out.println(lines+"line"+": "+token+" is wrong");}}}//字符串检查public static void stringCheck(String str){String token= String.valueOf(str.charAt(p++));char ch;for (;p<str.length();p++){ch=str.charAt(p);token+=ch;if (ch=='"'){break;}}if (token.charAt(token.length()-1)!='"'){System.out.println(lines+"line"+": "+token+" is wrong");}else {System.out.println("("+6+","+token+")");}}
}
实验结果
1、对于正确的输入:
public static void test(){int a=10;double b=20.2;double c=a+b;}

2、有不正确的输入:
public static double test(){double a=20.3.2.1;int 1111bbbb=10;System.out.println(a+b);String str="helloWorld";double c=124.、a++;return a+b+c;}


















