Java pass1汇编器的符号表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21213435/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 07:22:15  来源:igfitidea点击:

Symbol table of pass1 assembler

javaassemblysymbol-table

提问by chinu

I want to design a simple assembler for IBM360 assembly language.so i'm implementing symbol table first. i'm storing my symbols/labels in a separate file so as to compare it while generating the symbol table.the problem im facing is ,the incorrect location counter(LC) value due to unwanted comparisions.I'm able to detect the symbols but with the wrong LC value. can anyone guide me in modifying my code?

我想为 IBM360 汇编语言设计一个简单的汇编器。所以我首先实现符号表。我将我的符号/标签存储在一个单独的文件中,以便在生成符号表时进行比较。我面临的问题是,由于不需要的比较,位置计数器(LC)值不正确。我能够检测到符号但 LC 值错误。谁能指导我修改我的代码?

Here is my program :

这是我的程序:

import java.io.*; 
import java.lang.*; 

class SymbolTable
 { 
    public static void main(String args[]) throws Exception 
    { 
    FileReader fr = new FileReader("program.asm"); 
    BufferedReader br = new BufferedReader(fr); 
    String s,l; 
    String code[]=new String[100];
    String label[]=new String[100];

    int N=0,i,LOC=0,n=0,j;
    System.out.println("Assembly lang program :\n--------------------------");
    while((s = br.readLine()) != null)
    {
        code[N++]=s;
        System.out.println(s); 
    } 
    fr.close();
    FileReader labels = new FileReader("label.txt"); 
    BufferedReader buff = new BufferedReader(labels); 
    while((s = buff.readLine()) != null)
    {
        label[n++]=s;
    } 
    labels.close();
    System.out.println("\n\n SYMBOL TABLE :\n-------------------------------------------\nLABEL\tLC\tLENGTH\tRELATIVE/ABSOLUTE\n-------------------------------------------");
    for(i=0;i<N;i++)
    {
        for(j=0;j<n;j++)
        {           
                char codearr[]=new char[15];
                codearr=code[i].toCharArray();
                if(code[i].startsWith("USING"))
                {
                 break;
                }
                else if(code[i].startsWith(label[j]))
                {
                    System.out.println(label[j]+"\t"+LOC+"\t4\tR");
                    if(i==0)
                    {}
                    else
                    LOC=LOC+4;
                    break;                  
                }
                else if(codearr[1]=='R')   // for register addressing mode
                    LOC=LOC+2;
                else
                    LOC=LOC+4;
        }   
    }
    } 
 }

program.asm:

程序.asm:

JOHN START 
USING *,15
L 1,FIVE
A 1,FOUR
ST 1,TEMP
FOUR DC F '4'
FIVE DC F '5'
TEMP DS 1F
END

label.txt

标签.txt

JOHN
FOUR 
FIVE
TEMP

output :

输出 :

G:\programs>javac SymbolTable.java
G:\programs>java SymbolTable
Assembly lang program :
--------------------------
JOHN START
USING *,15
LR 1,FIVE
A 1,FOUR
ST 1,TEMP
FOUR DC F '4'
FIVE DC F '5'
TEMP DS 1F
END

 SYMBOL TABLE :
-------------------------------------------
LABEL   LC      LENGTH  RELATIVE/ABSOLUTE
-------------------------------------------
JOHN    0       4       R
FOUR    44      4       R
FIVE    56      4       R
TEMP    72      4       R

回答by blackcompe

Here's an example to help you see your way through. I'm not aware of the language ins and outs, but based on the input you provided, this example should help. It builds the symbol table from labels matched at the beginning of the opcode, which I assume is the correct syntax for demarcating code sections associated with a label. The code makes assumptions and doesn't check against possible conflicts, but you can figure all that out. Feel free to build off it.

这是一个示例,可帮助您了解自己的方法。我不知道语言的来龙去脉,但根据您提供的输入,此示例应该会有所帮助。它根据在操作码开头匹配的标签构建符号表,我认为这是划分与标签关联的代码部分的正确语法。该代码进行假设并且不检查可能的冲突,但您可以弄清楚所有这些。随意构建它。

Input

输入

The exact input you provided.

您提供的确切输入。

Output

输出

JOHN    0   true
FOUR    50  true
TEMP    78  true
FIVE    64  true

Code

代码

import java.io.File;
import java.io.IOException;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;

class SymbolTableBuilder
{
    public static SymbolTable build(String asm, String lbls)
    {
        return build(asm.split("\n"), lbls.split("\n"));
    }

    public static SymbolTable build(String[] asm, String[] lbls)
    {
        return build(Arrays.asList(asm), Arrays.asList(lbls));
    }

    public static SymbolTable build(File asm, File lbls)
    {
        //TODO
        return null;
    }

    public static SymbolTable build(List<String> asm, List<String> lbls)
    {
        SymbolTable tbl = new SymbolTable();
        int pos = 0;
        for (String opCode : asm) {
            String tok = opCode.split("\s+")[0];
            if (lbls.contains(tok))
                tbl.addSymbol(tok, new Symbol(tok, pos, true));
            pos += opCode.length() + 1; //account for newline
        }
        return tbl;
    }

    public static void main(String[] args) throws IOException
    {
        final String asm
            = "JOHN START\nUSING *,15\nL 1,FIVE\nA 1,FOUR\n"
            + "ST 1,TEMP\nFOUR DC F '4'\nFIVE DC F '5'\nTEMP DS 1F\nEND";

        final String lbls = "JOHN\nFOUR\nFIVE\nTEMP";

        for (Entry<String, Symbol> e : SymbolTableBuilder.build(asm, lbls))
            System.out.println(e.getValue());
    }

}

class SymbolTable implements Iterable<Entry<String, Symbol>>
{
    private Map<String, Symbol> syms;

    public SymbolTable()
    {
        syms = new HashMap<>();
    }

    public void addSymbol(String key, Symbol sym)
    {
        syms.put(key, sym);
    }

    public Symbol getSymbol(String key)
    {
        return syms.get(key);
    }

    @Override
    public Iterator<Entry<String, Symbol>> iterator()
    {
        return syms.entrySet().iterator();
    }
}

class Symbol
{
    String label;
    int loc;
    boolean relative;

    public Symbol(String label, int loc, boolean relative)
    {
        this.label = label;
        this.loc = loc;
        this.relative = relative;
    }

    @Override
    public int hashCode()
    {
        int hash = 3;
        hash = 29 * hash + Objects.hashCode(this.label);
        return hash;
    }

    @Override
    public boolean equals(Object obj)
    {
        if (obj == null) return false;
        if (getClass() != obj.getClass()) return false;
        final Symbol other = (Symbol) obj;
        if (!Objects.equals(this.label, other.label)) return false;
        return true;
    }

    @Override
    public String toString()
    {
        return label + "\t" + loc + "\t" + relative;
    }
}