标签:编译器-符号表
符号表是一种供编译器用于保存有关源程序构造的各种信息的数据结构,这些信息在编译器的分析阶段被逐步收集并放入符号表。
如我们输入
{int x;char y;{bool y; x; y; }x; y;}
期望生成:
{{x:int; y:bool;} x:int; y:char;}
内层块的x来源于外部。
package com.bigbear.main;
public class Code {
public static String content = "{int x;char y;{bool y; x; y; }x; y;}";
private static int index = 0;
public static char read() {
return content.charAt(index++);
}
public static boolean isEnd() {
return index > content.length() - 1;
}
}
package com.bigbear.symbols;
import java.util.Hashtable;
/**
* @author winney
* linkedSymbols 链接符号表
*/
public class Env {
@SuppressWarnings("rawtypes")
private Hashtable table;
protected Env prev;
@SuppressWarnings("rawtypes")
public Env(Env p){
table=new Hashtable();
prev=p;
}
public void put(String s,Symbol sym){
table.put(s, sym);
}
public Symbol get(String s){
for(Env e=this;e!=null;e=e.prev){
Symbol found=(Symbol)(e.table.get(s));
if(found!=null) return found;
}
return null;
}
}
package com.bigbear.lexer;
import java.io.IOException;
import java.util.Hashtable;
import com.bigbear.enums.tagVM_INSTRUCTION;
import com.bigbear.main.Code;
import com.bigbear.symbols.Env;
import com.bigbear.symbols.Symbol;
/**
* @author winney 词法分析器
*
*/
public class Lexer {
public int line = 1;
private char peek = ‘ ‘;
@SuppressWarnings("rawtypes")
private Hashtable words = new Hashtable();
private Env top = null;
private Env saved = null;
private StringBuffer result = new StringBuffer();
@SuppressWarnings({ "unchecked" })
private void reserve(Word t) {
words.put(t.lexeme, t);
}
public Lexer() {
reserve(new Word(Tag.TRUE, "true"));
reserve(new Word(Tag.FALSE, "false"));
reserve(new Word(Tag.TYPE, "int"));
reserve(new Word(Tag.TYPE, "char"));
reserve(new Word(Tag.TYPE, "bool"));
}
@SuppressWarnings("unchecked")
public Token scan() throws IOException {
if (Code.isEnd()) {
return null;
}
for (;; peek = (char) Code.read()) {
if (peek == ‘ ‘ || peek == ‘\t‘)
continue;
else if (peek == ‘\n‘)
line++;
else
break;
}
if (Character.isDigit(peek)) {
int v = 0;
do {
v = 10 * v + Character.digit(peek, 10);
peek = (char) Code.read();
} while (Character.isDigit(peek));
return new Num(v);
}
if (Character.isLetter(peek)) {
StringBuffer b = new StringBuffer();
do {
b.append(peek);
peek = (char) Code.read();
} while (Character.isLetterOrDigit(peek));
String s = b.toString();
Word w = (Word) words.get(s);
if (w != null)
return w;
w = new Word(Tag.ID, s);
words.put(s, w);
return w;
}
Token t = new Token(peek);
peek = ‘ ‘;
return t;
}
public String Parse() throws IOException {
Token token = scan();
Word w;
Symbol s;
while (token != null) {
switch (token.tag) {
case ‘{‘:
saved = top;
top = new Env(top);
result.append(‘{‘);
break;
case ‘}‘:
top = saved;
result.append(‘}‘);
break;
case Tag.TYPE:
w = (Word) token;
s = new Symbol(w.lexeme);
w = (Word) scan();
if (w.tag == Tag.ID)
top.put(w.lexeme, s);
break;
case Tag.ID:
w = (Word) token;
s = top.get(w.lexeme);
result.append(w.lexeme);
result.append(‘:‘);
result.append(s.type);
if (scan().tag == ‘;‘)
result.append(‘;‘);
break;
default:
break;
}
token = scan();
}
return result.toString();
}
public static void main(String[] args) {
Lexer lx = new Lexer();
try {
System.out.println(lx.Parse());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这里看到了我使用了预读的技巧
输入:{int x;char y;{bool y; x; y; }x; y;}
输出:{{x:int;y:bool;}x:int;y:char;}
标签:编译器-符号表
原文地址:http://blog.csdn.net/lingchixin/article/details/45000071