java语言的符号表_我的第一个编译器之符号表

符号表

符号表是一种供编译器用于保存有关源程序构造的各种信息的数据结构,这些信息在编译器的分析阶段被逐步收集并放入符号表。

如我们输入

{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;}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值