1:  package compiler;
   2:   
   3:  import java.io.BufferedReader;
   4:  import java.io.FileNotFoundException;
   5:  import java.io.FileReader;
   6:  import java.util.Arrays;
   7:   
   8:  public class Scanner {
   9:   
  10:      public int lineCnt=0;
  11:      private char curCh = ' ';
  12:      private String line;
  13:      public int lineLength = 0;
  14:      public int chCount = 0;
  15:      private int[] ssym;
  16:      private BufferedReader in;
  17:   
  18:      public Scanner(String filePath) {
  19:          try {
  20:              in = new BufferedReader(new FileReader(filePath));
  21:          } catch (FileNotFoundException ex) {
  22:              ex.printStackTrace();
  23:              System.out.println("***File not exist!***");
  24:          }
  25:          //设置单字符
  26:          ssym = new int[256];
  27:          Arrays.fill(ssym, Symbol.nul);
  28:          ssym['+'] = Symbol.plus;
  29:          ssym['-'] = Symbol.minus;
  30:          ssym['*'] = Symbol.mul;
  31:          ssym['/'] = Symbol.div;
  32:          ssym['('] = Symbol.lparen;
  33:          ssym[')'] = Symbol.rparen;
  34:          ssym['='] = Symbol.eql;
  35:          ssym[','] = Symbol.comma;
  36:          ssym['.'] = Symbol.peroid;
  37:          ssym[';'] = Symbol.semicolon;
  38:   
  39:      }
  40:   
  41:      //读取一个字符,为减少磁盘I/O次数,每次读取一行
  42:      void getch() {
  43:          if (chCount == lineLength) {
  44:              try {//如果读到行末尾,就重新读入一行
  45:                  String tmp="";
  46:                  while (tmp.equals("")) {
  47:                      tmp=in.readLine().trim()+' ';               //除去空行
  48:                  }
  49:                  line=tmp;
  50:                  lineCnt++;
  51:              } catch (Exception e) {
  52:                  // throw new Error("***program imcomplete!***");
  53:                  e.printStackTrace();
  54:                  System.out.println("***reading character meet with error!***");
  55:              }
  56:              lineLength = line.length();
  57:              chCount = 0;
  58:              System.out.println(line);
  59:          }
  60:          curCh = line.charAt(chCount++);
  61:      }
  62:   
  63:      //词法分析,获取一个词法分析符号,是词法分析器的重点
  64:      public Symbol getsym() {
  65:          Symbol sym;
  66:          while (curCh == ' ') {
  67:              getch();
  68:          }
  69:          if ((curCh >= 'a' && curCh <= 'z')||(curCh >= 'A' && curCh <= 'Z')) {
  70:              sym = matchKeywordOrIdentifier();                                     //关键字或者一般标识符
  71:          } else if (curCh >= '0' && curCh <= '9') {
  72:              sym = matchNumber();                                                       //数字
  73:          } else {
  74:              sym = matchOperator();                                                     //操作符
  75:          }
  76:          return sym;
  77:      }
  78:   
  79:      private Symbol matchKeywordOrIdentifier() {
  80:          StringBuffer sb = new StringBuffer();
  81:          do{
  82:              sb.append(curCh);
  83:              getch();
  84:          }while((curCh >= 'a' && curCh <= 'z')||(curCh>='A'&&curCh<='Z') || (curCh >= '0' && curCh <= '9'));
  85:   
  86:          String token = sb.toString();
  87:          int index = Arrays.binarySearch(Symbol.word, token);                           //搜索是不是保留字
  88:          Symbol sym = null;
  89:          if (index < 0) {
  90:              sym = new Symbol(Symbol.ident);                                            //一般标识符
  91:              sym.id = token;
  92:          } else {
  93:              sym = new Symbol(Symbol.wsym[index]);                                    //保留字对应的符号值0-31
  94:          }
  95:          return sym;
  96:      }
  97:   
  98:      private Symbol matchNumber() {
  99:          //统计数字位数
 100:          Symbol sym = new Symbol(Symbol.number);
 101:          do {                      
 102:              sym.num = 10 * sym.num + curCh - '0';                                    // 获取数字的值
 103:              getch();
 104:          } while (curCh >= '0' && curCh <= '9');                                    //!!!
 105:   
 106:          return sym;
 107:      }
 108:   
 109:      private Symbol matchOperator() {
 110:          Symbol sym = null;
 111:          switch (curCh) {
 112:              case ':':                                                                       // 赋值符号
 113:                  getch();
 114:                  if (curCh == '=') {
 115:                      sym = new Symbol(Symbol.becomes);
 116:                      getch();
 117:                  } else {
 118:                      sym = new Symbol(Symbol.nul);                               //不能识别的符号
 119:                  }
 120:                  break;
 121:              case '<':                                                                    //小于或者小于等于
 122:                  getch();
 123:                  if (curCh == '=') {
 124:                      sym = new Symbol(Symbol.leq);                             //是<=
 125:                      getch();
 126:                  } else if (curCh == '>') {
 127:                      sym = new Symbol(Symbol.neq);                           //是<>
 128:                      getch();
 129:                  } else {
 130:                      sym = new Symbol(Symbol.lss);                             //是<
 131:                  }
 132:                  break;
 133:              case '>':                                                      //大于或者大于等于
 134:                  getch();
 135:                  if (curCh == '=') {
 136:                      sym = new Symbol(Symbol.geq);                           //大于等于
 137:                      getch();
 138:                  } else {
 139:                      sym = new Symbol(Symbol.gtr);                            //大于
 140:                  }
 141:                  break;
 142:              default:
 143:                  sym = new Symbol(ssym[curCh]);
 144:                  if (sym.symtype != Symbol.peroid) {
 145:                      getch();
 146:                  }
 147:          }
 148:          return sym;
 149:      }
 150:  }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

PL/0编译器(java version) – Scanner.java的更多相关文章

  1. PL/0编译器(java version) - MainFrame.java

    1: /* 2: * To change this license header, choose License Headers in Project Properties. 3: * To chan ...

  2. PL/0编译器实践---后记

    花了几天时间,把清华版的<编译原理>一书中的PL/0编译器实践了一遍.颇有收获,记录如下: 理解代码的技巧,如何理解一份代码,比如这个程序,其逻辑相对于一般程序就比较复杂了,如何翻译,虚拟 ...

  3. PL/0编译器(java version)–Praser.java

    1: package compiler; 2:   3: import java.io.IOException; 4: import java.util.BitSet; 5:   6: /** 7: ...

  4. PL/0编译器(java version)–PL0.java

    1: package compiler; 2:   3: import java.io.BufferedWriter; 4: import java.io.FileWriter; 5:   6: /* ...

  5. PL/0编译器(java version) – SymbolTable.java

    1: package compiler; 2: //竟然没有对符号表检查大小,会溢出的. 3:   4: import java.io.IOException; 5:   6: public clas ...

  6. PL/0编译器(java version) - Interpreter.java

    1: package compiler; 2:   3: import java.io.BufferedReader; 4: import java.io.BufferedWriter; 5: imp ...

  7. PL/0编译器(java version) - Err.java

    1: package compiler; 2:   3: import java.io.BufferedWriter; 4:   5: public class Err { 6:   7: publi ...

  8. PL/0编译器(java version) – Symbol.java

    1: package compiler; 2:   3: /** 4: * 采用全局变量sym来存储符号码,并用全局变量id和num来传递语义值 5: * 6: * @author jiangnan ...

  9. PL/0编译器(java version)–Pcode.java

    1: package compiler; 2:   3: /** 4: * //虚拟机指令 5: * 6: * @author jiangnan 7: * 8: */ 9: public class ...

随机推荐

  1. Socket网络编程--FTP客户端

    Socket网络编程--FTP客户端(1)(Windows) 已经好久没有写过博客进行分享了.具体原因,在以后说. 这几天在了解FTP协议,准备任务是写一个FTP客户端程序.直接上干货了. 0.了解F ...

  2. VC维含义

    VC维含义的个人理解 有关于VC维可以在很多机器学习的理论中见到,它是一个重要的概念.在读<神经网络原理>的时候对一个实例不是很明白,通过这段时间观看斯坦福的机器学习公开课及相关补充材料, ...

  3. scrollHeight,scrollLeft,offsetHeight,offsetLeft

    scrollHeight:内部元素的绝对高度,包含内部元素的隐藏的部分scrollWidth:内部元素的绝对宽度,包含内部元素的隐藏的部分 scrollLeft:设置或获取位于对象左边界和窗口中目前可 ...

  4. python学习笔记整理——集合 set

    python学习整理笔记--集合 set 集合的用途:成员测试和消除重复的条目,进行集合运算 注意:花括号或set()函数可以用于创建集合. 注意:若要创建一个空的集合你必须使用set(),不能用{} ...

  5. 【Python】[函数] 函数的参数与递归函数

    一.函数的参数1.位置参数2.默认参数 n就是默认参数 def power(x,n=2): s=1 while n > 0: n = n - 1 s = s * x return s 默认参数有 ...

  6. 常用数据库高可用和分区解决方案(1) — MySQL篇

    在本文中我们将会讨论MySQL.Oracle.MongoDB.Redis以及Oceanbase数据库,大家可能会奇怪为什么看不到有名关系型数据库MSSQL.DB2或者有名NoSQL数据库Hbase.L ...

  7. mvc的自带json序列化的datetime在js中的解析

    默认仅序列化后的日期格式是这样的:'/Date(124565787989)/'(数字随便敲的,数字表示相对于1970年的总毫秒数) 在js中借助eval函数,eval函数的意义:将参数中的字符串当作j ...

  8. JNI系列——简便开发流程

    1.编写Java代码 2.选中工程目录--右键单击Android Tools--Add Native Support 3.输入要生成的库名 4.到工程目录中jni目录下对自动生成文件和.mk文件进行相 ...

  9. Ceph Zabbix plugin 插件和模板

    由于Ceph项目中的 Celemeter 缺乏告警功能和监控平台的统一性要求, YY 云平台Ceph集群的监控需求,都是在团队已有的zabbix平台基础上开发完成的. 在已有的git开源项目基础上做了 ...

  10. find常见用法

    Linux中find常见用法示例 ·find   path   -option   [   -print ]   [ -exec   -ok   command ]   {} \; find命令的参数 ...