频道栏目
首页 > 程序开发 > 软件开发 > Java > 正文
我的第一个编译器之符号表
2015-04-13 10:35:33      个评论    来源:TO TOP CODER  
收藏   我要投稿

符号表

符号表是一种供编译器用于保存有关源程序构造的各种信息的数据结构,这些信息在编译器的分析阶段被逐步收集并放入符号表。
如我们输入
{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;}

点击复制链接 与好友分享!回本站首页
相关TAG标签 编译器 符号
上一篇:Java算法-第一个数字
下一篇:快速回忆正则表达式
相关文章
图文推荐
点击排行

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站