专栏首页Nicky's blogJava编写的C语言词法分析器

Java编写的C语言词法分析器

Java编写的C语言词法分析器

    这是java编写的C语言词法分析器,我也是参考很多代码,然后将核心代码整理起来,准备放在QQ空间和博客上,目的是互相学习借鉴,希望可以得到高手改进。这个词法分析器实现的功能有打开文件、保存文件、打开帮助文档、文本域内容的剪切和复制和黏贴、进行词法分析 程序的项目结构如图,Word类和Unidentifiable类是两个JavaBean类,存放的参数有两个row(整型)、word(String),row用于获取行数,word用于获取标识符,LexerFrame是词法分析器的界面类,Analyze封装了进行词法分析的核心代码 ,doc文件夹放一个帮助文档,当用户点击帮助按钮时可以弹出来以帮助用户使用。 Github项目链接:https://github.com/u014427391/lexer1.1.0,欢迎star //核心程序:

package com.lexer;

import java.util.ArrayList;

/** *1~20号为关键字,用下标表示,i+1就是其机器码;21~40号为操作符,用下标表示,i+21就是其机器码;41~60号为分界符, *  用下标表示,i+41就是其机器码;用户自定义的标识符,其机器码为51;常数的机器码为52;不可以识别的标识符,其机器码为0 */  public class Analyze {

 //关键字  private String keyword[]={"int","long","char","if","else","for","while","return","break","continue",    "switch","case","default","float","double","void","struct","static","do","short"};  //运算符  private String operator[]={"+","-","*","/","%","=",">","<","!","==","!=",">=","<=","++","--","&","&&","||","[","]"};  //分界符  private String delimiter[]={",",";","(",")","{","}","\'","\"",":","#"};  public Analyze() {  }  /**   * 判断是否是数字   */  public boolean isDigit(char ch){   if(ch>='0'&&ch<='9'){    return true;   }else{    return false;   }  }  /**   * 判断是否是字母的函数   */  public boolean isLetter(char ch){   if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){    return true;   }else{    return false;   }  }  /**   * 判断是否由两个运算符组成   */  public boolean isTwoOperator(String str,char ch){   char lc;   int flag=0;   if(str.length()>1||str.length()==0){//字符数大于2和无字符的情况    return false;   }else{//字符数等于2的情况    lc=str.charAt(str.length()-1);    if(ch=='='&&(lc=='>'||lc=='<'||lc=='='||lc=='!')){    }else if(ch=='+'&&lc=='+'){    }else if(ch=='-'&&lc=='-'){    }else if(ch=='|'&&lc=='|'){    }else if(ch=='&'&&lc=='&'){    }else{     return false;//否就返回false    }    return true;//其它符号的情况都返回true   }  }  /**   * 获取关键字的机器码   */  public int getKeywordOpcodes(String str){   int i;    for(i=0;i<keyword.length;i++){    if(str.equals(keyword[i]))     break;   }   if(i<keyword.length){    return i+1;//返回关键字的机器码   }else{    return 0;   }  }  /**   * 获取操作符的机器码   */  public int getOperatorOpcodes(String str){   int i;   for(i=0;i<operator.length;i++){    if(str.equals(operator[i]))     break;   }   if(i<operator.length)    return i+21;//返回操作符的机器码   else    return 0;  }  /**   * 获取分界符的机器码   */  public int getDelimiterOpcodes(String str){   int i;   for(i=0;i<delimiter.length;i++){    if(str.equals(delimiter[i]))     break;   }   if(i<delimiter.length)    return i+41;//返回分界符的机器码   else    return 0;  }  /**   * 判断字符是否可以识别   */  public boolean isIdent(String str){   char ch;   int i;   for(i=0;i<str.length();i++){    ch=str.charAt(i);    //非数字串的情况和非由英文字母组成的字符串    if((i==0&&!isLetter(ch))||(!isDigit(ch)&&!isLetter(ch))){     break;    }   }   if(i<str.length()){    return false;      }else{    return true;      }  }  /**   *   * 预处理函数   */  public String preFunction(String str){   String ts="";   int i;   char ch,nc;   //这里的i<str.length()-1   for(i=0;i<str.length()-1;i++){     ch=str.charAt(i);    nc=str.charAt(i+1);    if(ch=='\n'){//如果字符是换行符,将\n换成$     ch='$';     ts=ts+ch;    }else if(ch==' '||ch=='\r'||ch=='\t'){     if(nc==' '||nc=='\r'||ch=='\t'){      continue;//连续' '或者'\t'或者'\r'的情况,直接跳过     }else{      ch=' ';//一个' '或者'\t'或者'\r'的情况,将这些字符换成' '      ts=ts+ch;     }    }else{     ts=ts+ch;//将字符连起来    }   }   ch=str.charAt(str.length()-1);   if(ch!=' '&&ch!='\r'&&ch!='\t'&&ch!='\n'){    ts=ts+ch;   }   return ts;  }  /**   * 将字符串分成一个个单词,存放在数组列表   */  public ArrayList<Word> divide(String str){   ArrayList<Word> list=new ArrayList<Word>();   String s="";   char ch;   int i;   int row=1;   for(i=0;i<str.length();i++){    ch=str.charAt(i);    if(i==0&&ch==' ')//字符串的第一个字符     continue;    if(ch==' '){//' '或者'\t'或者'\r'的情况     if(s!=""){      list.add(new Word(row, s));      s="";//置空     }else{      continue;     }    }else if(isDigit(ch)||isLetter(ch)){     if(s==""||isDigit(s.charAt(s.length()-1))||isLetter(s.charAt(s.length()-1))){      s = s + ch;     }else{      list.add(new Word(row, s));      s = "";      s=s + ch;     }     }else{     if(isTwoOperator(s, ch)){//两个运算符的情况      s = s + ch;     }else{      if(s==""&&ch!='$'){       s = s + ch;      }else if(s==""&&ch=='$'){//若检测到$符号,就换行       row++;//行数加一      }else{       list.add(new Word(row, s));       s = "";       if(ch!='$'){        s=s + ch;       }else{        row++;       }      }     }     }   }   if(s!=""){    list.add(new Word(row, s));   }   return list;  }  /**   * 判断字符串是数字串,单个字符,还是一个字符串   */  public int check(String str){   char ch;   ch=str.charAt(0);   if(ch>='0'&&ch<='9'){    return 1;//数字串   }   if(str.length()==1)    return 2;//单个字符   else    return 3;//一个字符串  }  /**   *   * 检查字符串是否为数字串,返回其机器码   */  public int checkDigit(String str){   int i;   char ch;   for(i=0;i<str.length();i++){    ch=str.charAt(i);    if(ch>'9'||ch<'0')     break;   }   if(i<str.length()){    return 0;//不可识别的情况   }else{    return 52;//常数   }  }  /**   *   * 检查字符串是否为单个字符,返回其机器码   */  public int checkChar(String str){   if(getOperatorOpcodes(str)!=0){//操作符    return getOperatorOpcodes(str);   }else if(getDelimiterOpcodes(str)!=0){//分界符    return getDelimiterOpcodes(str);   }else if(isIdent(str)){    return 51;//用户自定义标识符的机器码   }else{    return 0;//不可以被识别的标识符,机器码为0   }  }  /**   *   * 检查字符串是否为字符串,返回其机器码   */  public int checkString(String str){   if(getOperatorOpcodes(str)!=0){//操作符    return getOperatorOpcodes(str);   }else if(getKeywordOpcodes(str)!=0){//关键字    return getKeywordOpcodes(str);     }else if(isIdent(str)){    return 51;//用户自定义标识符的机器码     }else{    return 0;//不可以被识别的标识符,机器码为0     }  } }

//******************************************************************************************************************** 在界面类写这个方法来调用方法 /**   * 词法分析   */  public void doTokenizing(){   consoleTextArea.setText(null);   ArrayList<Word> wlist=new ArrayList<Word>();   ArrayList<Unidentifiable> ulist=new ArrayList<Unidentifiable>();   String s,ts,str;   Word word;   int i;   int opcodes=-1;   int errorNum=0;   int count=0;   s=fileContentTextArea.getText();   if(s.length()>1){    ts=analyze.preFunction(s);    wlist=analyze.divide(ts);    values=new String[wlist.size()][3];    while(wlist.size()>0){     word=(Word)wlist.remove(0);     str=word.getWord();     i=analyze.check(str);     switch (i) {     case 1:      opcodes=analyze.checkDigit(str);      break;     case 2:      opcodes=analyze.checkChar(str);      break;     case 3:      opcodes=analyze.checkString(str);      break;     }     if(opcodes==0){      Unidentifiable u=new Unidentifiable(word.getRow(), str);      ulist.add(u);      errorNum++;     }     values[count][0]=String.valueOf(word.getRow());     values[count][1]=str;     values[count][2]=String.valueOf(opcodes);     count++;    }    //更新表格内容    DefaultTableModel model=(DefaultTableModel)table.getModel();    while(model.getRowCount()>0){     model.removeRow(model.getRowCount()-1);    }         model.setDataVector(values,title);    table=new JTable(model);     consoleTextArea.append("共有"+errorNum+"处错误!"+"\n");     while (ulist.size()>0) {      int r;      String string;      Unidentifiable uni=ulist.remove(0);      r=uni.getRow();      string=uni.getWord();      consoleTextArea.append("第"+r+"行:"+"错误,"+string+"\n");     }   }else{    int j;    j=JOptionPane.showConfirmDialog(this, "请输入程序!");    if(j!=JOptionPane.YES_OPTION){     return;    }   }  }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 聊聊flink的InputFormatSourceFunction

    flink-streaming-java_2.11-1.6.2-sources.jar!/org/apache/flink/streaming/api/envi...

    codecraft
  • IntelliJ IDEA JDK 8 性能调优

    IntelliJ IDEA 问题描述问题原因解决方法调优后观察为什么要选择用户`idea.vmoptions`文件

    芋道源码
  • PDF有锁,不让复制?不让编辑?甚至不让打印?再见!

    多年以来,PDF凭借着超级级级级级级级级好的兼容性,称霸了电子文档的世界,你不用担心自己辛辛苦苦做的Word、PPT、Excel发给别人看却成了乱七八糟的排版,...

    课代表
  • 聊聊flink的RichParallelSourceFunction

    flink-streaming-java_2.11-1.6.2-sources.jar!/org/apache/flink/streaming/api/func...

    codecraft
  • Java必会技术图,是可以帮你薪资翻倍的

    可以说,Java是现阶段中国互联网公司中,覆盖度最广的研发语言,掌握了Java技术体系,不管在成熟的大公司,快速发展的公司,还是创业阶段的公司,都能有立足之地。

    奋斗蒙
  • Java开发中遇到的那些坑!

    之前在这个手册刚发布的时候看过一遍,当时感觉真是每个开发者都应该必读的一本手册,最近由于在总结一些我们日常开发中容易忽略的问题,可能是最低级的编码常见问题,往往...

    互扯程序
  • javascript基础修炼(10)——VirtualDOM和基本DFS

    Virtual-DOM,即虚拟DOM树。浏览器在解析文件时,会将html文档转换为document对象,在浏览器环境中运行的脚本文件都可以获取到它,通过操作do...

    大史不说话
  • 「小程序JAVA实战」小程序的事件(11)

    IT故事会
  • 比特币与130多种山寨币的数字货币开源交易库CCXT(CryptoCurrency eXchange)

    CCXT(CryptoCurrency eXchange)交易库,一个JavaScript/Python/PHP加密货币交易库,支持超过100种山寨币与比特币交...

    笔阁
  • 分布式作业系统 Elastic-Job-Lite 源码分析 —— 作业监听器

    摘要: 原创出处 http://www.iocoder.cn/Elastic-Job/job-listener/ 「芋道源码」欢迎转载,保留摘要,谢谢!

    芋道源码

扫码关注云+社区

领取腾讯云代金券