目录
词法分析说明
实现原理分析
代码实现
结果图
词法分析说明
编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。并依次输出各个单词的内部编码及单词符号自身值。
例如:
如源程序为C语言。输入如下一段:
main()
{
int a=-5,b=4,j;
if(a>=b)
j=a-b;
else j=b-a;
}
要求输出:
(”main”,1,1)
(”(”,5)
(”)”,5)
(”{”,5)
(”int”,1,2)
(”a”,2)
(”=”,4)
(”-5”,3)
(”,”,5)
(”b”,2)
(”=”,4)
(”4”,3)
(”,”,5)
(”j”,2)
(”;”,5)
(”if”,1,3)
(”(”,5)
(”a”,2)
(”>=”,4)
(”b”,2)
(”)”,5)
(”j”,2)
(”=”,4)
(”a”,2)
(”-”,4)
(”b”,2)
(”;”,5)
(”else”,1,4)
(”j”,2)
(”=”,4)
(”b”,2)
(”-”,4)
(”a”,2)
(”;”,5)
(”}”,5)
实现原理分析
1. 以上述示例代码中,首先明确出现了哪些内容
(1)关键字:例如 int ,if , else
(2)标识符:例如 a , b ,j
(3)常量:例如 5 , 4
(4)运算符:例如 = , - ,+
(5)界限符:例如 [ ] , { } ,;
2. 基本转换图
3. 基本流程图
编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。并依次输出各个单词的内部编码及单词符号自身值。
例如:
如源程序为C语言。输入如下一段:
main()
{
int a=-5,b=4,j;
if(a>=b)
j=a-b;
else j=b-a;
}
要求输出:
(”main”,1,1)
(”(”,5)
(”)”,5)
(”{”,5)
(”int”,1,2)
(”a”,2)
(”=”,4)
(”-5”,3)
(”,”,5)
(”b”,2)
(”=”,4)
(”4”,3)
(”,”,5)
(”j”,2)
(”;”,5)
(”if”,1,3)
(”(”,5)
(”a”,2)
(”>=”,4)
(”b”,2)
(”)”,5)
(”j”,2)
(”=”,4)
(”a”,2)
(”-”,4)
(”b”,2)
(”;”,5)
(”else”,1,4)
(”j”,2)
(”=”,4)
(”b”,2)
(”-”,4)
(”a”,2)
(”;”,5)
(”}”,5)
1. 以上述示例代码中,首先明确出现了哪些内容
(1)关键字:例如 int ,if , else
(2)标识符:例如 a , b ,j
(3)常量:例如 5 , 4
(4)运算符:例如 = , - ,+
(5)界限符:例如 [ ] , { } ,;
2. 基本转换图
3. 基本流程图
代码实现
实现的详细过程已在代码中注释
注意!!
代码中有一个内容(关于负数)没有实现,希望有大佬可以改进
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.BufferedReader;
public class cffx20192697 {
public static void main(String[] args) {
cffx20192697.read("D:\text01.txt");
}
public static String[] KeyWord = {
"main","print","printf","scan","scanf","auto","breakcase","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"
};
//定义标识符数组(t=2)
public static String[] Identifier = new String[1000];
public static String[] Operator = {
"+", "-", "*", "/","%","++","--",
"==","!=",">","<",">=","<=",
"&&","||","!",
"&","|","^","~","<<",">>",
"=","+=","-=","*=","/=","%=","<<=",">>=","&=","^=","!=",
"?"
};
public static String[] LineBreaks = {
"(", ")", "{", "}" , ";" , "," , """ , "[" , "]" , "'"
};
//定义判断信号
public static int index=0;
public static int sign=0;
//传入一个字符串s进行判断
public static void Judge(String s) {
//进行遍历
for(int i = 0 ; i < s.length() ;){
//调用String类中的的方法charAT():返回指定索引处的字符
char t = s.charAt(i);
//排除空格和回车换行后,进入循环
if( t!=' '&&t!='t' ){
StringBuilder str = new StringBuilder();
if (t >= 'a' && t <= 'z') {
// 当读取到不是大小写字母或者数字时候判断为一个单词读取完成
while (t >= 'a' && t <= 'z' || t >= 'A' && t <= 'Z' || t >= '0' && t <= '9'||t=='_') {
//进行字符拼接
str.append(t);
//读取下一个字符
t = s.charAt(++i);
}
//创建一个信号作为接下来的判断标准
int sign=0;
//对关键字数组进行遍历
for(int j=0;j "+"("+"1"+","+(j+1)+")");
sign=1;
}
}
//程序进行到这里说明str不是关键字,但是符合关键字的判断条件说明这是一个标识符
if(sign==0){
//由于数组下标从0开始,所以需要++
Identifier[index++]= str.toString();
System.out.println(str+" ——> "+"(2)");
}
//当头字符是在0~9范围内时,说明这是一个常量
}else if(t >= '0' && t <= '9'){
StringBuilder number = new StringBuilder();
while (t >= '0' && t <= '9') {
//进行数字拼接
number.append(t);
t = s.charAt(++i);
System.out.println(number+" ——> "+"(3)");
}
}else{
//定义两个信号,用于后面判断是否为非法字符
int sign1=0;
int sign2=0;
//两位界限符或运算符
if(i+1!=s.length()){
//对运算符数组进行遍历
for (String value : Operator) {
//调用equals方法进行判断,拼接后的字符串是否是运算符数组中的
if (value.equals(t + String.valueOf(s.charAt(i + 1)))) {
System.out.println(value + " ——> " + "(4)");
i++;
sign1 = 1;
sign2 = 1;
}
}
//对界限符数组进行遍历
for (String lineBreak : LineBreaks) {
//调用equals方法进行判断,拼接后的字符串是否是界限符数组中的
if (lineBreak.equals(t + String.valueOf(s.charAt(i + 1)))) {
System.out.println(lineBreak + " ——> " + "(5)");
i++;
sign1 = 1;
sign2 = 1;
}
}
}
//一位界限符或运算符
if(sign1==0){
for (String value : Operator) {
if (value.equals(String.valueOf(t))) {
System.out.println(value + " ——> " + "(4)");
sign2 = 1;
}
}
for (String lineBreak : LineBreaks) {
if (lineBreak.equals(String.valueOf(t))) {
System.out.println(lineBreak + " ——> " + "(5)");
sign2 = 1;
}
}
}
//当sign一直为0;就说明这是一个非法字符
if(sign2 == 0) {
System.out.println(t+"是一个非法字符!请仔细修改!");
}
//一轮判断结束,开始下一轮判断
i++;
}
}
//空格和换行情况下,直接跳过
else{
i++;
}
}
}
//定义一个读取文件,以及代码行数的方法
public static void read(String fileName) {
File file = new File(fileName);
BufferedReader reader = null;
try {
//换行
System.out.println();
System.out.println("结果说明:(m,n){m:单词类型,n:表中位置} m包含以下五种情况——>1:关键词 2:标识符 3:常数 4:运算符 5:界限符 ");
reader = new BufferedReader(new FileReader(file));
String tempString;
int line = 1;
//一次读入一行,直到读入null为文件结束
while ((tempString = reader.readLine()) != null) {
//输出行号
System.out.println("line " + line + ": " + Result(Result(tempString)));
Judge(Result(Result(tempString)));
System.out.println();
System.out.println();
line++;
}
//调用close()方法,结束文件的读取
reader.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException ignored) {
}
}
}
}
//定义一个方法用于判断注释符(和//)
public static String Result(String t) {
for (int i = 0; i < t.length(); i++) {
if(t.charAt(i) == '*'&&t.charAt(i+1)=='/'){
sign=0;
//调用substring方法进行单词的截取
return t.substring(i+2);
}
if(sign==0){
if (t.charAt(i) == '/'&&t.charAt(i+1)=='/') {
return t.substring(0, i);
}
if(t.charAt(i) == '/'&&t.charAt(i+1)=='*'){
sign=1;
return t.substring(0, i);
}
}
}
if(sign ==0){
return t;
}
return "";
}
}
结果图
实现的详细过程已在代码中注释
注意!!
代码中有一个内容(关于负数)没有实现,希望有大佬可以改进
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.BufferedReader;
public class cffx20192697 {
public static void main(String[] args) {
cffx20192697.read("D:\text01.txt");
}
public static String[] KeyWord = {
"main","print","printf","scan","scanf","auto","breakcase","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"
};
//定义标识符数组(t=2)
public static String[] Identifier = new String[1000];
public static String[] Operator = {
"+", "-", "*", "/","%","++","--",
"==","!=",">","<",">=","<=",
"&&","||","!",
"&","|","^","~","<<",">>",
"=","+=","-=","*=","/=","%=","<<=",">>=","&=","^=","!=",
"?"
};
public static String[] LineBreaks = {
"(", ")", "{", "}" , ";" , "," , """ , "[" , "]" , "'"
};
//定义判断信号
public static int index=0;
public static int sign=0;
//传入一个字符串s进行判断
public static void Judge(String s) {
//进行遍历
for(int i = 0 ; i < s.length() ;){
//调用String类中的的方法charAT():返回指定索引处的字符
char t = s.charAt(i);
//排除空格和回车换行后,进入循环
if( t!=' '&&t!='t' ){
StringBuilder str = new StringBuilder();
if (t >= 'a' && t <= 'z') {
// 当读取到不是大小写字母或者数字时候判断为一个单词读取完成
while (t >= 'a' && t <= 'z' || t >= 'A' && t <= 'Z' || t >= '0' && t <= '9'||t=='_') {
//进行字符拼接
str.append(t);
//读取下一个字符
t = s.charAt(++i);
}
//创建一个信号作为接下来的判断标准
int sign=0;
//对关键字数组进行遍历
for(int j=0;j "+"("+"1"+","+(j+1)+")");
sign=1;
}
}
//程序进行到这里说明str不是关键字,但是符合关键字的判断条件说明这是一个标识符
if(sign==0){
//由于数组下标从0开始,所以需要++
Identifier[index++]= str.toString();
System.out.println(str+" ——> "+"(2)");
}
//当头字符是在0~9范围内时,说明这是一个常量
}else if(t >= '0' && t <= '9'){
StringBuilder number = new StringBuilder();
while (t >= '0' && t <= '9') {
//进行数字拼接
number.append(t);
t = s.charAt(++i);
System.out.println(number+" ——> "+"(3)");
}
}else{
//定义两个信号,用于后面判断是否为非法字符
int sign1=0;
int sign2=0;
//两位界限符或运算符
if(i+1!=s.length()){
//对运算符数组进行遍历
for (String value : Operator) {
//调用equals方法进行判断,拼接后的字符串是否是运算符数组中的
if (value.equals(t + String.valueOf(s.charAt(i + 1)))) {
System.out.println(value + " ——> " + "(4)");
i++;
sign1 = 1;
sign2 = 1;
}
}
//对界限符数组进行遍历
for (String lineBreak : LineBreaks) {
//调用equals方法进行判断,拼接后的字符串是否是界限符数组中的
if (lineBreak.equals(t + String.valueOf(s.charAt(i + 1)))) {
System.out.println(lineBreak + " ——> " + "(5)");
i++;
sign1 = 1;
sign2 = 1;
}
}
}
//一位界限符或运算符
if(sign1==0){
for (String value : Operator) {
if (value.equals(String.valueOf(t))) {
System.out.println(value + " ——> " + "(4)");
sign2 = 1;
}
}
for (String lineBreak : LineBreaks) {
if (lineBreak.equals(String.valueOf(t))) {
System.out.println(lineBreak + " ——> " + "(5)");
sign2 = 1;
}
}
}
//当sign一直为0;就说明这是一个非法字符
if(sign2 == 0) {
System.out.println(t+"是一个非法字符!请仔细修改!");
}
//一轮判断结束,开始下一轮判断
i++;
}
}
//空格和换行情况下,直接跳过
else{
i++;
}
}
}
//定义一个读取文件,以及代码行数的方法
public static void read(String fileName) {
File file = new File(fileName);
BufferedReader reader = null;
try {
//换行
System.out.println();
System.out.println("结果说明:(m,n){m:单词类型,n:表中位置} m包含以下五种情况——>1:关键词 2:标识符 3:常数 4:运算符 5:界限符 ");
reader = new BufferedReader(new FileReader(file));
String tempString;
int line = 1;
//一次读入一行,直到读入null为文件结束
while ((tempString = reader.readLine()) != null) {
//输出行号
System.out.println("line " + line + ": " + Result(Result(tempString)));
Judge(Result(Result(tempString)));
System.out.println();
System.out.println();
line++;
}
//调用close()方法,结束文件的读取
reader.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException ignored) {
}
}
}
}
//定义一个方法用于判断注释符(和//)
public static String Result(String t) {
for (int i = 0; i < t.length(); i++) {
if(t.charAt(i) == '*'&&t.charAt(i+1)=='/'){
sign=0;
//调用substring方法进行单词的截取
return t.substring(i+2);
}
if(sign==0){
if (t.charAt(i) == '/'&&t.charAt(i+1)=='/') {
return t.substring(0, i);
}
if(t.charAt(i) == '/'&&t.charAt(i+1)=='*'){
sign=1;
return t.substring(0, i);
}
}
}
if(sign ==0){
return t;
}
return "";
}
}



