第五次作业--词法分析程序的设计与实现(20191010)
词法分析程序(Lexical Analyzer)要求:
- 从左至右扫描构成源程序的字符流
- 识别出有词法意义的单词(Lexemes)
- 返回单词记录(单词类别,单词本身)
- 滤掉空格
- 跳过注释
- 发现词法错误
程序结构:
输入:字符流(什么输入方式,什么数据结构保存)
处理:
–遍历(什么遍历方式)
–词法规则
输出:单词流(什么输出形式)
–二元组
单词类别:
1.标识符(10)
2.无符号数(11)
3.保留字(一词一码)
4.运算符(一词一码)
5.界符(一词一码)
|
单词符号 |
种别码 |
单词符号 |
种别码 |
|
begin |
1 |
: |
17 |
|
if |
2 |
:= |
18 |
|
then |
3 |
< |
20 |
|
while |
4 |
<= |
21 |
|
do |
5 |
<> |
22 |
|
end |
6 |
> |
23 |
|
l(l|d)* |
10 |
>= |
24 |
|
dd* |
11 |
= |
25 |
|
+ |
13 |
; |
26 |
|
- |
14 |
( |
27 |
|
* |
15 |
) |
28 |
|
/ |
16 |
# |
0 |
因为自己对运用Java语言编写程序比较熟悉,所以用Java编写了这次的词法分析程序。将字符与种别码分别对应起来,区分数字分隔符。
程序代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
public class LexicalAnalyzer {
static String[] keyWords=new String[]{"main","if","then","while","do","static",
"int","double","struct","break","else",
"long","switch","case","typedef","char",
"return","const","float","short","continue",
"for","void","sizeof"}; //关键字种别码从1开始
static char ch;
static int index;
static int syn, sum=0, row;
static String str="";
static StringBuilder word=new StringBuilder(""); //建立StringBuilder,方便读取文字信息追加
public static void main(String[] args) {
index=0;
row=1;//从第一行开始扫描
System.out.println("请输入一段C语言源程序字符串(以#符号结束):");
BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
try{
do{
String testStr;
testStr=bf.readLine();
str+=testStr;
ch=testStr.charAt(testStr.length()-1); //读到单词最后一个字符
}while(ch!='#');
}catch(IOException e){
e.printStackTrace();
}
index=0; //重置单词字符索引
do{
Analyzer();
//输出数字及种别码
if (syn==26) {
System.out.println("("+syn+","+sum+")");
}
else if (syn==-1) {
System.out.println("没有该符号的种别码!!!");
}
else if (syn==-2) {
}
else {
System.out.println("("+syn+","+word+")");
}
}while(syn!=0);
}
static void Analyzer(){
//将单词容器清空
word.delete(0, word.length());
ch=str.charAt(index++);//获取单词每一个字符
//跳过空格
while(ch==' '){
ch=str.charAt(index++);
}
if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){ //判断是关键字还是标识符
while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){
word.append(ch);
ch=str.charAt(index++);
}
index--; //回退标记
syn=25;
String s=word.toString();
//判断为关键字
for(int i=0; i<keyWords.length; i++){
if(s.equals(keyWords[i])){
syn=i+1;
break;
}
}
}
//判断为是数字
else if((ch>='0'&&ch<='9')){
sum=0;
while((ch>='0'&&ch<='9')){
sum=sum*10+ch-'0';
ch=str.charAt(index++);
}
index--;
syn=26;
}
//判断为各种字符
else switch(ch){
case '<':
word.append(ch);
ch=str.charAt(index++);
//判断是否是<=
if(ch=='='){
word.append(ch);
syn=35;
}
//判断是否是<>
else if(ch=='>'){
word.append(ch);
syn=34;
}
//判断为<
else{
syn=33;
index--;
}
break;
case '>':
word.append(ch);
ch=str.charAt(index++);
//判断是否是>=
if(ch=='='){
word.append(ch);
syn=37;
}
//判断是>
else{
syn=36;
index--;
}
break;
case '*':
word.append(ch);
ch=str.charAt(index++);
//判断是否是**
if(ch=='*'){
word.append(ch);
syn=31;
}
//判断是*
else{
syn=13;
index--;
}
break;
case '=':
word.append(ch);
ch=str.charAt(index++);
//判断是否是==
if(ch=='='){
syn=32;
word.append(ch);
}
//判断是=
else{
syn=38;
index--;
}
break;
case '/':
word.append(ch);
ch=str.charAt(index++);
//判断是否是注释
if(ch=='/'){
while(ch!=' '){
ch=str.charAt(index++); //判断里面是否有空格
}
syn=-2;
break;
}
//判断是/
else{
syn=30;
index--;
}
break;
//判断是+
case '+':
syn=27;
word.append(ch);
break;
//判断是-
case '-':
syn=28;
word.append(ch);
break;
//判断是;
case ';':
syn=41;
word.append(ch);
break;
//判断是(
case '(':
syn=42;
word.append(ch);
break;
//判断是)
case ')':
syn=43;
word.append(ch);
break;
//判断是#
case '#':
syn=0;
word.append(ch);
break;
//判断是回车
case '\n':
syn=-2;
word.append(ch);
break;
//没有种别码
default:
syn=-1;
}
}
}
运行结果:


浙公网安备 33010602011771号