编译原理实验一 -无符号数的词法分析程序

一、实验目的和要求:

1.掌握词法分析的基本思想,并用高级语言编写无符号数的词法分析程序。

2.要求从键盘上输入一串字符(包括字母、数字等),最后以“;”结束,编

写程序识别出其中的无符号数

二、实验平台:

   Java语言

三、主要实验内容及结果:

实验内容:

词法分析的主要任务是:扫描源程序,识别单词,生成属性字。单词的种类一般分为四种:关键字、标识符、常数、特殊符号,无符号数是常数中的一种,无符号数的词法分析难点在于带指数的无符号数的识别。

无符号数文法规则可定义如下:

<无符号数>→<无符号实数>│<无符号整数>

<无符号实数>→<无符号整数>.<数字串>[E<比例因子>]│

<无符号整数>E<比例因子>

<比例因子>→<有符号整数>

<有符号整数>→[+│-]<无符号整数>

<无符号整数>→<数字串>

<数字串>→<数字>{<数字>}

<数字>→0 │1 │2 │3...... │9

             程序代码:

import java.util.ArrayList;
import java.util.Scanner;
public class Unsigned {
    private ArrayList<Word> wordList;
    public static void main(String[] args) {
        Unsigned unsigned = new Unsigned();// 读入单词列表unsigned.inputWordList();// 识别单词列表for (Word word : unsigned.wordList) {// 识别单词unsigned.whichType(word);
            String temp = word.getCJ2();
            if (temp != null) {
                int index = temp.lastIndexOf(".0");
                if (index == temp.length() - 2)
                    word.setCJ2(temp.substring(0, index));
            }
        }// 输出单词列表unsigned.printWordList();
    }// 识别单词private void whichType(Word word) {
        int w = 0;
        int p = 0;
        int j = 0;
        int e = 1;
        int d = 0;
        String chars[] = word.getStr().split("");// 从第一个字符开始int i = 0;
        String current_char = chars[i];// 数字否?if (!isNum(current_char)) {
            word.setCJ1("出错");
            return;
        } else {
            while (true) {
                d = Integer.parseInt(current_char);
                w = w * 10 + d;
                current_char = chars[++i];// 数字否?if (isNum(current_char)) {
                    continue;
                } else {// '.'?if (current_char.equals(".")) {
                        current_char = chars[++i];// 数字否?if (!isNum(current_char)) {
                            word.setCJ1("出错");
                            return;
                        } else {
                            while (true) {
                                d = Integer.parseInt(current_char);
                                w = w * 10 + d;
                                j = j + 1;
                                current_char = chars[++i];// 数字否?if (isNum(current_char)) {
                                    continue;
                                } else {// 'E'?if (current_char.equals("E")) {
                                        isE(current_char, chars, i, word, w, p, j, e, d);
                                        return;
                                    } else {// 退一字符word.setCJ1("实型");
                                        word.setCJ2((w * Math.pow(10, e * p - j)) + "");
                                        return;
                                    }
                                }
                            }
                        }
                    } else {// 'E'?if (current_char.equals("E")) {
                            isE(current_char, chars, i, word, w, p, j, e, d);
                            return;
                        } else {// 退一字符word.setCJ1("整型");
                            word.setCJ2((w * Math.pow(10, e * p - j)) + "");
                            return;
                        }
                    }
                }
            }
        }
    }
    private void isE(String current_char, String[] chars, int i, Word word, int w, int p, int j, int e, int d) {
        current_char = chars[++i];// '-'?if (current_char.equals("-")) {
            e = -1;
            current_char = chars[++i];// 数字否?if (isNum(current_char)) {
                while (true) {
                    d = Integer.parseInt(current_char);
                    p = p * 10 + d;
                    current_char = chars[++i];
                    if (isNum(current_char)) {
                        continue;
                    } else {// 退一字符word.setCJ1("实型");
                        word.setCJ2((w * Math.pow(10, e * p - j)) + "");
                        return;
                    }
                }
            } else {
                word.setCJ1("出错");
                return;
            }
        } else {// '+'?if (current_char.equals("+")) {
                current_char = chars[++i];// 数字否?if (isNum(current_char)) {
                    while (true) {
                        d = Integer.parseInt(current_char);
                        p = p * 10 + d;
                        current_char = chars[++i];
                        if (isNum(current_char)) {
                            continue;
                        } else {// 退一字符word.setCJ1("实型");
                            word.setCJ2((w * Math.pow(10, e * p - j)) + "");
                            return;
                        }
                    }
                } else {
                    word.setCJ1("出错");
                    return;
                }
            } else {// 数字否?if (isNum(current_char)) {
                    while (true) {
                        d = Integer.parseInt(current_char);
                        p = p * 10 + d;
                        current_char = chars[++i];
                        if (isNum(current_char)) {
                            continue;
                        } else {// 退一字符word.setCJ1("实型");
                            word.setCJ2((w * Math.pow(10, e * p - j)) + "");
                            return;
                        }
                    }
                } else {
                    word.setCJ1("出错");
                    return;
                }
            }
        }
    }// 是否为数字private boolean isNum(String string) {
        return "0123456789".contains(string);
    }// 读入单词列表private void inputWordList() {
        System.out.println("12996 0269 0E Es265 ;要求从键盘上输入一串字符(包括字母、数字等),最后以“;”结束");
        Scanner scanner = new Scanner(System.in);
        String temp = scanner.nextLine().replace(";", "");
        scanner.close();
        String[] strs = temp.split(" ");
        wordList = new ArrayList<Word>();
        for (String str : strs) {
            Word word = new Word();
            word.setStr(str + "#");
            wordList.add(word);
        }
    }// 输出单词列表private void printWordList() {
        for (Word word : wordList) {
            System.out.println(word.getStr() + "\t" + word.getCJ2() + "\t" + word.getCJ1());
        }
    }// 单词类private class Word {// str记原始单词private String str;// CJ1记类型private String CJ1;// CJ1记数值private String CJ2;
        public String getStr() {
            return str;
        }
        public void setStr(String str) {
            this.str = str;
        }
        public String getCJ1() {
            return CJ1;
        }
        public void setCJ1(String cJ1) {
            CJ1 = cJ1;
        }
        public String getCJ2() {
            return CJ2;
        }
        public void setCJ2(String cJ2) {
            CJ2 = cJ2;
        }
    }
}

运行结果:

 

四、心得体会

词法分析阶段是编译过程的第一个阶段,是编译的基础。这个阶段的任务是从左到右一个字符一个字符地读入源程序,即对构成源程序的字符流进行扫描然后根据构词规则识别单词(也称单词符号或符号)。

#include<iostream> #include<cctype> #include<cstring> #include<cmath> using namespace std; int w=0; //尾累加器 int p=0; //指累加器 int j=0; //十进制小器 int e=1; //用来记录十进制的符号,当指为正时为1,为负时为-1 int i=0; //用来标志元素位置 int d=0; //用来表示每个值型元素对应的值 const int N=40;//用来确定输入识别符的最大长度 char data[N];//存放输入的识别符 bool is_digit; //标志是否是字 string CJ1;//确定是整形还是实型 double CJ2;//记值 //函声明 void check(char c);//检查首字母是否是字的函 void deal_integer(char c);//处理识别符的整部分 void deal_point(char c);//用来处理小部分 void deal_index(char c);//用来处理指部分 void s_next();// 确定实型 void z_next();//确定整型 void last();// 计算 CJ2 void error();//程序中错误处理程序 void deal();//处理函主体 int main(){ //主函 cout<<"please input your data,and its maximum length is "<<N<<":"<<endl;//等待用户输入识别符 cin>>data; deal();//处理函主体 last();// 计算 CJ2 system("pause"); return 0; } void check(char c) //判断输入的首字母是否是字 { is_digit=isdigit(c); while(is_digit!=true){//输入的首字母不是字时 cout<<"\nError! Try again.."<<endl;//要求重新输入 cin>>data; check(data[0]); } } void deal_integer(char c){//处理识别符的整部分 d=(int)c-48; w=w*10+d; i++; if(isdigit(data[i])!=0)//下一个仍是值时,调用程序本身 deal_integer(data[i]); } void deal_point(char c){//用来处理小部分 int temp=i; if(isdigit(c)!=0)//是值字符时 deal_integer(c); else { error(); //错误处理程序 deal();//处理函主体 } j=i-temp;//记录十进制小 } void deal_index(char c){//用来处理指部分 if(c=='-') {e=-1;i++;}//是'-'号时 else {if(c=='+') i++;//是'+' 号时 else { if(isdigit(c)==false) //非值字符时 { error();//错误处理程序 deal();//处理函主体 } else { d=(int)c-48;//把输入字符转换为整型 goto pro2;} } } if(isdigit(data[i])!=0) pro1: d=(int)(data[i])-48; pro2: p=p*10+d; i++; if(isdigit(data[i])!=0)//是值字符时 goto pro1; else if(data[i]!='\0'){//非结束标志 error();//错误处理程序 deal();//处理函主体 } else s_next(); // 确定实型 } void s_next(){// 确定实型 i--;//退一个字符 CJ1="实型"; } void z_next(){//确定整型 i--;//退一个字符 CJ1="整型"; } void last(){// 计算 CJ2 CJ2=w*pow((double)10,e*p-j); cout<<CJ1<<": "<<CJ2<<endl;//输出 } void error(){//程序中错误处理程序 cout<<"\nError! Try again.."<<endl;//重新输入据 cin>>data; p=0;w=0;j=0; //所有全局变量重新初始化 e=1;i=0;d=0; //exit(0); } void deal(){ check(data[0]);//判断输入的首字母是否是字 deal_integer(data[i]);//处理识别符的整部分 if(data[i]=='.') { deal_point(data[++i]);//用来处理小部分 if(data[i]=='e'||data[i]=='E')//如果是e或E时 deal_index(data[++i]);//用来处理指部分 else if(data[i]!='\0') { error();//错误处理程序 deal();//处理函主体 } else s_next();// 确定实型 } else { if(data[i]=='e'||data[i]=='E')//如果是e或E时 { deal_index(data[++i]);//用来处理指部分 //CJ1="整型"; } else if(data[i]!='\0'){ //非结束标志 error();//错误处理程序 deal();//处理函主体 } else z_next();//确定整型 } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值