PL/0编译器(java version) – Scanner.java
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的更多相关文章
- PL/0编译器(java version) - MainFrame.java
1: /* 2: * To change this license header, choose License Headers in Project Properties. 3: * To chan ...
- PL/0编译器实践---后记
花了几天时间,把清华版的<编译原理>一书中的PL/0编译器实践了一遍.颇有收获,记录如下: 理解代码的技巧,如何理解一份代码,比如这个程序,其逻辑相对于一般程序就比较复杂了,如何翻译,虚拟 ...
- PL/0编译器(java version)–Praser.java
1: package compiler; 2: 3: import java.io.IOException; 4: import java.util.BitSet; 5: 6: /** 7: ...
- PL/0编译器(java version)–PL0.java
1: package compiler; 2: 3: import java.io.BufferedWriter; 4: import java.io.FileWriter; 5: 6: /* ...
- PL/0编译器(java version) – SymbolTable.java
1: package compiler; 2: //竟然没有对符号表检查大小,会溢出的. 3: 4: import java.io.IOException; 5: 6: public clas ...
- PL/0编译器(java version) - Interpreter.java
1: package compiler; 2: 3: import java.io.BufferedReader; 4: import java.io.BufferedWriter; 5: imp ...
- PL/0编译器(java version) - Err.java
1: package compiler; 2: 3: import java.io.BufferedWriter; 4: 5: public class Err { 6: 7: publi ...
- PL/0编译器(java version) – Symbol.java
1: package compiler; 2: 3: /** 4: * 采用全局变量sym来存储符号码,并用全局变量id和num来传递语义值 5: * 6: * @author jiangnan ...
- PL/0编译器(java version)–Pcode.java
1: package compiler; 2: 3: /** 4: * //虚拟机指令 5: * 6: * @author jiangnan 7: * 8: */ 9: public class ...
随机推荐
- Socket网络编程--FTP客户端
Socket网络编程--FTP客户端(1)(Windows) 已经好久没有写过博客进行分享了.具体原因,在以后说. 这几天在了解FTP协议,准备任务是写一个FTP客户端程序.直接上干货了. 0.了解F ...
- VC维含义
VC维含义的个人理解 有关于VC维可以在很多机器学习的理论中见到,它是一个重要的概念.在读<神经网络原理>的时候对一个实例不是很明白,通过这段时间观看斯坦福的机器学习公开课及相关补充材料, ...
- scrollHeight,scrollLeft,offsetHeight,offsetLeft
scrollHeight:内部元素的绝对高度,包含内部元素的隐藏的部分scrollWidth:内部元素的绝对宽度,包含内部元素的隐藏的部分 scrollLeft:设置或获取位于对象左边界和窗口中目前可 ...
- python学习笔记整理——集合 set
python学习整理笔记--集合 set 集合的用途:成员测试和消除重复的条目,进行集合运算 注意:花括号或set()函数可以用于创建集合. 注意:若要创建一个空的集合你必须使用set(),不能用{} ...
- 【Python】[函数] 函数的参数与递归函数
一.函数的参数1.位置参数2.默认参数 n就是默认参数 def power(x,n=2): s=1 while n > 0: n = n - 1 s = s * x return s 默认参数有 ...
- 常用数据库高可用和分区解决方案(1) — MySQL篇
在本文中我们将会讨论MySQL.Oracle.MongoDB.Redis以及Oceanbase数据库,大家可能会奇怪为什么看不到有名关系型数据库MSSQL.DB2或者有名NoSQL数据库Hbase.L ...
- mvc的自带json序列化的datetime在js中的解析
默认仅序列化后的日期格式是这样的:'/Date(124565787989)/'(数字随便敲的,数字表示相对于1970年的总毫秒数) 在js中借助eval函数,eval函数的意义:将参数中的字符串当作j ...
- JNI系列——简便开发流程
1.编写Java代码 2.选中工程目录--右键单击Android Tools--Add Native Support 3.输入要生成的库名 4.到工程目录中jni目录下对自动生成文件和.mk文件进行相 ...
- Ceph Zabbix plugin 插件和模板
由于Ceph项目中的 Celemeter 缺乏告警功能和监控平台的统一性要求, YY 云平台Ceph集群的监控需求,都是在团队已有的zabbix平台基础上开发完成的. 在已有的git开源项目基础上做了 ...
- find常见用法
Linux中find常见用法示例 ·find path -option [ -print ] [ -exec -ok command ] {} \; find命令的参数 ...