码迷,mamicode.com
首页 > 其他好文 > 详细

我的第一个编译器之符号表

时间:2015-04-12 17:50:22      阅读:132      评论:0      收藏:0      [点我收藏+]

标签:编译器-符号表

符号表

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!