zoukankan      html  css  js  c++  java
  • 编译原理 作业五

    词法分析程序(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

    word类:

    public class word {     //二元组类结构
    private int typenum; //种别码
    private String word;// 扫描得到的词
    public int getTypenum() {
    return typenum;
    }
    public void setTypenum(int typenum) {
    this.typenum = typenum;
    }
    public String getWord() {
    return word;
    }
    public void setWord(String word) {
    this.word = word;
    }

    }

    keywords类:

    public class keywords {
    private static String KEYWORDS = "关键字";//关键字判断
    private word words;
    private char[] input = new char[255];
    private char[] token = new char[255];
    private int p_input=0;//用于输入字符记数
    private int p_token=0;//用于数字字符记数
    private char ch; //获取单个字符

    private String[] rwtab = {"begin", "if", "then","while", "do", "end", KEYWORDS};

    public keywords(char [] input){
    this.input = input;

    }

    public char ch_getCh(){ //获取下一个字符,用于多位符号判断
    if (p_input<input.length){
    ch=input[p_input];
    p_input++;
    }
    return ch;
    }

    public void getbch(){ //获取标识符或空格的下一位字符
    while ((ch == ' '||ch ==' ')&&(p_input<input.length)){
    ch = input[p_input];
    p_input++;

    }

    }

    public void concat(){ //连接字符
    token[p_token] = ch;
    p_token++;
    token[p_token]='';

    }

    public boolean letter() { //判断字符是否为字母

    if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z')

    return true;

    else

    return false;

    }

    public boolean num() { // 判断字符是否为数字

    if(ch>='0'&&ch<='9')

    return true;

    else

    return false;

    }


    public void re() {//回退一个字符

    p_input--;

    }

    public String dtb() {
    int num = token[0] - 48;
    for(int i = 1; i < p_token; i++) {
    num = num * 10 + token[i] - 48;
    }
    StringBuilder result = new StringBuilder(); //字符串连接
    while(num>0) {
    int r = num % 2;
    int s = num / 2;
    result.append(r);
    num = s;
    }
    return result.reverse().toString();
    }
    public int reserve() { // 用于检查token字符串内是否存在关键字
    int i=0;
    while(rwtab[i].compareTo(KEYWORDS)!=0) {
    if(rwtab[i].compareTo(new String(token).trim()) == 0) {//移除字符串两侧的空白字符或其他预定义字符
    return i+1;
    }
    i++;
    }
    return 10;
    }

    public word scan() //开始扫描的大哥函数
    {
    token = new char[255];
    word myWord = new word();
    myWord.setTypenum(10);
    myWord.setWord("");
    p_token=0;
    ch_getCh();
    getbch();

    if(letter()) { //找出标识符
    while(letter()||num()) {
    concat();
    ch_getCh();
    }
    re();
    myWord.setTypenum(reserve());
    myWord.setWord(new String(token).trim());
    return myWord;
    }
    else if(num()) {
    while(num()) {
    concat();
    ch_getCh();
    }
    re();
    myWord.setTypenum(11);
    myWord.setWord(new String(token).trim()); //输出token中的数字串字符形式//
    myWord.setWord(dtb()); //输出token中的数字串10进制值的二进制字符串形式
    return myWord;
    }
    else
    switch (ch) {
    case '=':
    myWord.setTypenum(25);
    myWord.setWord("=");
    return myWord;
    case '+':
    myWord.setTypenum(13);
    myWord.setWord("+");
    return myWord;
    case '-':
    myWord.setTypenum(14);
    myWord.setWord("-");
    return myWord;
    case '*':
    myWord.setTypenum(15);
    myWord.setWord("*");
    return myWord;
    case '/':
    ch_getCh(); //识别单行注释,个人用了30备注
    if (ch == '/') {
    while(ch_getCh() != ' ');
    myWord.setTypenum(30);
    myWord.setWord("\n");
    return myWord;
    }
    //识别多行注释,个人用31来表示
    if(ch=='*') {
    String string = "";
    while(true) {
    if (ch == '*') {
    if (ch_getCh() == '/') { //找到多行注释结尾
    myWord.setTypenum(31);
    myWord.setWord(string);
    return myWord;
    }
    re();
    }
    if (ch_getCh() == ' ') { //找到多行注释的下一行
    string += "\n";
    }
    }
    }
    re();
    myWord.setTypenum(16);
    myWord.setWord("/");
    return myWord;
    case ':':
    ch_getCh();
    if(ch=='=') {
    myWord.setTypenum(18);
    myWord.setWord(":=");
    return myWord;
    }
    re();
    myWord.setTypenum(17);
    myWord.setWord(":");
    return myWord;
    case '<':
    ch_getCh();
    if(ch=='=') {
    myWord.setTypenum(21);
    myWord.setWord("<=");
    return myWord;
    }
    else if (ch == '>') {
    myWord.setTypenum(22);
    myWord.setWord("<>");
    return myWord;
    }
    re();
    myWord.setTypenum(20);
    myWord.setWord("<");
    return myWord;
    case '>':
    ch_getCh();
    if(ch=='=') {
    myWord.setTypenum(24);
    myWord.setWord(">=");
    return myWord;
    }
    re();
    myWord.setTypenum(23);
    myWord.setWord(">");
    return myWord;
    case ';':
    myWord.setTypenum(26);
    myWord.setWord(";");
    return myWord;
    case '(':
    myWord.setTypenum(27);
    myWord.setWord("(");
    return myWord;
    case ')':
    myWord.setTypenum(28);
    myWord.setWord(")");
    return myWord;
    case ' ':
    myWord.setTypenum(30);
    myWord.setWord("\n");
    return myWord;
    case '#':
    myWord.setTypenum(0);
    myWord.setWord("#");
    return myWord;
    default:
    concat();
    myWord.setTypenum(-1);
    myWord.setWord("其他字符 "" + new String(token).trim() + """);
    return myWord;
    }
    }

    }


    main类:
    import java.io.*;
    import java.util.ArrayList;
    import java.util.Scanner;

    public class main {
    private File inputFile;
    private File outputFile;
    private String fileContent;
    private ArrayList<word> list = new ArrayList<>();
    public main(String input,String output) {
    inputFile = new File(input);
    outputFile = new File(output);
    }

    public String getContent() {
    StringBuilder stringBuilder = new StringBuilder();
    try(Scanner reader = new Scanner(inputFile)) {
    while (reader.hasNextLine()) {
    String line = reader.nextLine();
    stringBuilder.append(line + " ");
    }
    } catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    return fileContent = stringBuilder.toString();
    }

    public void analyze(String fileContent) {
    int over = 1;
    word word = new word();
    keywords scanner = new keywords(fileContent.toCharArray());
    while (over != 0) {
    word = scanner.scan();
    list.add(word);
    over = word.getTypenum();
    } saveResult();
    }

    public void saveResult() {
    if (!outputFile.exists())
    try {
    outputFile.createNewFile();
    } catch (IOException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
    }
    try(Writer writer = new FileWriter(outputFile)){
    for (word word : list) {
    writer.write("(" + word.getTypenum() + " ," + word.getWord() + ") ");
    }
    } catch (IOException e) {
    e.printStackTrace();
    }
    }

    public static void main(String[] args) {
    main Mains = new main("C:\Users\曾梓楷\Desktop\1.txt","C:\Users\曾梓楷\Desktop\output.txt");
    Mains.analyze(Mains.getContent());
    }
    }

    1.txt:
    int main(){
     int n,i,j,k;
     printf("请输入班级人数:");
     scanf("%d",&n);
     struct student Stu[n];
     
     for(i=0;i<n;i++){
      printf("请按顺序输入第%d位学生姓名,学号和成绩: ",i+1);
      printf("姓名 学号 成绩 ");
      scanf("%s %d %d",Stu[i].name,&Stu[i].num,&Stu[i].cj);
     }
     for(i=0;i<n-1;i++)
      for(j=0;j<n-i-1;j++)
       if(Stu[j].cj<Stu[j+1].cj)                  
       {
        t=Stu[j];
        Stu[j]=Stu[j+1];
        Stu[j+1]=t;
       }
       printf("他们的排名如下: ");
       for(i=0;i<n;i++){
        printf("%s %d %d ",Stu[i].name,Stu[i].num,Stu[i].cj);
       }
     #

    output.txt文件:
    (10 ,int)
    (10 ,main)
    (27 ,()
    (28 ,))
    (32 ,{)
    (30 , )
    (10 ,int)
    (10 ,n)
    (-1 ,其他字符 ",")
    (10 ,i)
    (-1 ,其他字符 ",")
    (10 ,j)
    (-1 ,其他字符 ",")
    (10 ,k)
    (26 ,;)
    (30 , )
    (10 ,printf)
    (27 ,()
    (-1 ,其他字符 """)
    (-1 ,其他字符 "请")
    (-1 ,其他字符 "输")
    (-1 ,其他字符 "入")
    (-1 ,其他字符 "班")
    (-1 ,其他字符 "级")
    (-1 ,其他字符 "人")
    (-1 ,其他字符 "数")
    (-1 ,其他字符 ":")
    (-1 ,其他字符 """)
    (28 ,))
    (26 ,;)
    (30 , )
    (10 ,scanf)
    (27 ,()
    (-1 ,其他字符 """)
    (-1 ,其他字符 "%")
    (10 ,d)
    (-1 ,其他字符 """)
    (-1 ,其他字符 ",")
    (-1 ,其他字符 "&")
    (10 ,n)
    (28 ,))
    (26 ,;)
    (30 , )
    (10 ,struct)
    (10 ,student)
    (10 ,Stu)
    (-1 ,其他字符 "[")
    (10 ,n)
    (-1 ,其他字符 "]")
    (26 ,;)
    (30 , )
    (30 , )
    (10 ,for)
    (27 ,()
    (10 ,i)
    (25 ,=)
    (11 ,)
    (26 ,;)
    (10 ,i)
    (20 ,<)
    (10 ,n)
    (26 ,;)
    (10 ,i)
    (13 ,+)
    (13 ,+)
    (28 ,))
    (32 ,{)
    (30 , )
    (10 ,printf)
    (27 ,()
    (-1 ,其他字符 """)
    (-1 ,其他字符 "请")
    (-1 ,其他字符 "按")
    (-1 ,其他字符 "顺")
    (-1 ,其他字符 "序")
    (-1 ,其他字符 "输")
    (-1 ,其他字符 "入")
    (-1 ,其他字符 "第")
    (-1 ,其他字符 "%")
    (10 ,d)
    (-1 ,其他字符 "位")
    (-1 ,其他字符 "学")
    (-1 ,其他字符 "生")
    (-1 ,其他字符 "姓")
    (-1 ,其他字符 "名")
    (-1 ,其他字符 ",")
    (-1 ,其他字符 "学")
    (-1 ,其他字符 "号")
    (-1 ,其他字符 "和")
    (-1 ,其他字符 "成")
    (-1 ,其他字符 "绩")
    (17 ,:)
    (-1 ,其他字符 "")
    (10 ,n)
    (-1 ,其他字符 """)
    (-1 ,其他字符 ",")
    (10 ,i)
    (13 ,+)
    (11 ,1)
    (28 ,))
    (26 ,;)
    (30 , )
    (10 ,printf)
    (27 ,()
    (-1 ,其他字符 """)
    (-1 ,其他字符 "姓")
    (-1 ,其他字符 "名")
    (-1 ,其他字符 "学")
    (-1 ,其他字符 "号")
    (-1 ,其他字符 "成")
    (-1 ,其他字符 "绩")
    (-1 ,其他字符 "")
    (10 ,n)
    (-1 ,其他字符 """)
    (28 ,))
    (26 ,;)
    (30 , )
    (10 ,scanf)
    (27 ,()
    (-1 ,其他字符 """)
    (-1 ,其他字符 "%")
    (10 ,s)
    (-1 ,其他字符 "%")
    (10 ,d)
    (-1 ,其他字符 "%")
    (10 ,d)
    (-1 ,其他字符 """)
    (-1 ,其他字符 ",")
    (10 ,Stu)
    (-1 ,其他字符 "[")
    (10 ,i)
    (-1 ,其他字符 "]")
    (-1 ,其他字符 ".")
    (10 ,name)
    (-1 ,其他字符 ",")
    (-1 ,其他字符 "&")
    (10 ,Stu)
    (-1 ,其他字符 "[")
    (10 ,i)
    (-1 ,其他字符 "]")
    (-1 ,其他字符 ".")
    (10 ,num)
    (-1 ,其他字符 ",")
    (-1 ,其他字符 "&")
    (10 ,Stu)
    (-1 ,其他字符 "[")
    (10 ,i)
    (-1 ,其他字符 "]")
    (-1 ,其他字符 ".")
    (10 ,cj)
    (28 ,))
    (26 ,;)
    (30 , )
    (33 ,})
    (30 , )
    (10 ,for)
    (27 ,()
    (10 ,i)
    (25 ,=)
    (11 ,)
    (26 ,;)
    (10 ,i)
    (20 ,<)
    (10 ,n)
    (14 ,-)
    (11 ,1)
    (26 ,;)
    (10 ,i)
    (13 ,+)
    (13 ,+)
    (28 ,))
    (30 , )
    (10 ,for)
    (27 ,()
    (10 ,j)
    (25 ,=)
    (11 ,)
    (26 ,;)
    (10 ,j)
    (20 ,<)
    (10 ,n)
    (14 ,-)
    (10 ,i)
    (14 ,-)
    (11 ,1)
    (26 ,;)
    (10 ,j)
    (13 ,+)
    (13 ,+)
    (28 ,))
    (30 , )
    (2 ,if)
    (27 ,()
    (10 ,Stu)
    (-1 ,其他字符 "[")
    (10 ,j)
    (-1 ,其他字符 "]")
    (-1 ,其他字符 ".")
    (10 ,cj)
    (20 ,<)
    (10 ,Stu)
    (-1 ,其他字符 "[")
    (10 ,j)
    (13 ,+)
    (11 ,1)
    (-1 ,其他字符 "]")
    (-1 ,其他字符 ".")
    (10 ,cj)
    (28 ,))
    (30 , )
    (32 ,{)
    (30 , )
    (10 ,t)
    (25 ,=)
    (10 ,Stu)
    (-1 ,其他字符 "[")
    (10 ,j)
    (-1 ,其他字符 "]")
    (26 ,;)
    (30 , )
    (10 ,Stu)
    (-1 ,其他字符 "[")
    (10 ,j)
    (-1 ,其他字符 "]")
    (25 ,=)
    (10 ,Stu)
    (-1 ,其他字符 "[")
    (10 ,j)
    (13 ,+)
    (11 ,1)
    (-1 ,其他字符 "]")
    (26 ,;)
    (30 , )
    (10 ,Stu)
    (-1 ,其他字符 "[")
    (10 ,j)
    (13 ,+)
    (11 ,1)
    (-1 ,其他字符 "]")
    (25 ,=)
    (10 ,t)
    (26 ,;)
    (30 , )
    (33 ,})
    (30 , )
    (10 ,printf)
    (27 ,()
    (-1 ,其他字符 """)
    (-1 ,其他字符 "他")
    (-1 ,其他字符 "们")
    (-1 ,其他字符 "的")
    (-1 ,其他字符 "排")
    (-1 ,其他字符 "名")
    (-1 ,其他字符 "如")
    (-1 ,其他字符 "下")
    (17 ,:)
    (-1 ,其他字符 "")
    (10 ,n)
    (-1 ,其他字符 """)
    (28 ,))
    (26 ,;)
    (30 , )
    (10 ,for)
    (27 ,()
    (10 ,i)
    (25 ,=)
    (11 ,)
    (26 ,;)
    (10 ,i)
    (20 ,<)
    (10 ,n)
    (26 ,;)
    (10 ,i)
    (13 ,+)
    (13 ,+)
    (28 ,))
    (32 ,{)
    (30 , )
    (10 ,printf)
    (27 ,()
    (-1 ,其他字符 """)
    (-1 ,其他字符 "%")
    (10 ,s)
    (-1 ,其他字符 "%")
    (10 ,d)
    (-1 ,其他字符 "%")
    (10 ,d)
    (-1 ,其他字符 "")
    (10 ,n)
    (-1 ,其他字符 """)
    (-1 ,其他字符 ",")
    (10 ,Stu)
    (-1 ,其他字符 "[")
    (10 ,i)
    (-1 ,其他字符 "]")
    (-1 ,其他字符 ".")
    (10 ,name)
    (-1 ,其他字符 ",")
    (10 ,Stu)
    (-1 ,其他字符 "[")
    (10 ,i)
    (-1 ,其他字符 "]")
    (-1 ,其他字符 ".")
    (10 ,num)
    (-1 ,其他字符 ",")
    (10 ,Stu)
    (-1 ,其他字符 "[")
    (10 ,i)
    (-1 ,其他字符 "]")
    (-1 ,其他字符 ".")
    (10 ,cj)
    (28 ,))
    (26 ,;)
    (30 , )
    (33 ,})
    (30 , )
    (0 ,#)
    由于选取的测试代码为C语言代码,有一些边界符和字符都混合了
  • 相关阅读:
    解决svn working copy locked问题
    如何:给代码加上书签
    Ext Gantt Web甘特图自定义任务树
    Ext Gantt Web甘特图数据结构
    配置Apache服务器(2)
    Ext Gantt Web自定义条形图
    安装Apache服务器(1)
    IF YOU HAVE A DREAM, GO FOR IT RIGHT NOW
    发现自己是这么不理智
    这班上的
  • 原文地址:https://www.cnblogs.com/zzkai/p/11653531.html
Copyright © 2011-2022 走看看