Artificial Intelligence Programming Lab(AIPLab) 討論區

Please login or register.

請輸入帳號, 密碼以及預計登入時間

新聞:

[慶賀]恭喜亞大獲《泰晤士報》亞洲最佳大學排名第83名,國內排名第十名-20170201

作者 主題: [公告] SIC 組譯器 PassOne C#版本  (閱讀 3654 次)

admin

  • 管理員
  • Hero Member
  • *****
  • 文章: 1798
    • 檢視個人資料
[公告] SIC 組譯器 PassOne C#版本
« 於: 五月 06, 2010, 11:20:59 am »
程式碼: [Select]
using System;
using System.IO;
using System.Globalization;
using System.Collections.Generic;
namespace PassOne
{
    class Program
    {
        static string filename1, filename2;
        static int nlineNo;
        static string Label, Opcode, Oprand, Line;
        static bool IsCommentLine;
        static StreamReader sr;
        static StreamWriter sw;
        static int Location, LOCCTR;
        static Dictionary<string, int> SYMTAB = new Dictionary<string, int>();
        /*SIC Instruction:
         * ADD,AND,COMP,DIV,J,JEQ,JGT,JLT,JSUB,LDA,LDCH,LDL,LDX,MUL,OR,RD,RSUB,STA,STCH,STL,STX,SUB,TD,TIO,TIX,WD
        */
        static string[] OPTAB = new string[] { "ADD", "AND", "COMP", "DIV", "J", "JEQ", "JGT", "JLT", "JSUB", "LDA", "LDCH", "LDL", "LDX", "MUL", "OR", "RD", "RSUB", "STA", "STCH", "STL", "STX", "SUB", "TD", "TIO", "TIX", "WD" };
        static void Main(string[] args)
        {
            string ErrorMessage;
           
            filename1 = args[0];
            filename2 = args[1];
            nlineNo = 0;
            sr = new StreamReader(filename1);
            sw = new StreamWriter(filename2);


           //read first input line
            ReadFirstLine();
            if (Opcode == "START")//if OPCODE = 'START' then
            {
                LOCCTR = int.Parse(Oprand, NumberStyles.HexNumber); Location = LOCCTR;//save #[OPERAND] as starting address
                WriteThisLine();
                ReadNextLine();
            }
            else
                LOCCTR = 0; Location = 0;

            while (Opcode != "END")
            {
                Location = LOCCTR;
                if (!IsCommentLine)
                {
                    if (Label.Length > 0)
                    {
                        if (SYMTAB.ContainsKey(Label))
                        {
                            ErrorMessage = "Duplicate symbol:" + Label;
                            break;
                        }
                        else
                        {
                            SYMTAB.Add(Label, LOCCTR);
                        }
                    }
                    if (SearchOPTAB(Opcode))
                        LOCCTR += 3;
                    else if (Opcode == "WORD")
                        LOCCTR += 3;
                    else if (Opcode == "RESW")
                        LOCCTR += 3 * int.Parse(Oprand);
                    else if (Opcode == "RESB")
                        LOCCTR += int.Parse(Oprand);
                    else if (Opcode == "BYTE")
                        LOCCTR += FindConstantLength(Oprand);
                    else
                    {
                        ErrorMessage = "Invalid operation code:" + Label;
                        break;
                    }
                }
                WriteThisLine();
                ReadNextLine();
            }
            WriteLastLine();
            sr.Close();
            sw.Close();
     
        }
        static bool ReadFirstLine()
        {
            return ReadNextLine();
        }
        static bool ReadNextLine()
        {
            if (sr.Peek() == -1) return false;

            Line = sr.ReadLine();
            if (Line[0] == '.')
            {
                IsCommentLine = true;
            }
            else
            {
                IsCommentLine = false;
                Label = Line.Substring(0, 8).Trim(); ;
                Opcode = Line.Substring(9, 8).Trim(); ;
                if (Line.Length >= 36)
                    Oprand = Line.Substring(17, 16).Trim();
                else
                    Oprand = Line.Substring(17).Trim();
            }
            nlineNo = nlineNo + 5;
            return true;
        }
        static bool SearchOPTAB(string opcode)
        {
            for (int i = 0; i < OPTAB.Length; i++)
            {
                if (opcode == OPTAB[i])
                {
                    return true;
                }
            }
            return false;
        }
        static int FindConstantLength(string oprand)
        {
            if (oprand.Length <3)
                return 0;
            int Q1, Q2;
            int nLen = 0;
            switch (oprand[0])
            {
                case 'C':
                    Q1 = oprand.IndexOf('\'');
                    if (Q1 >= 0)
                    {
                        Q2 = oprand.IndexOf('\'', Q1+1);
                        if (Q2 > Q1)
                            nLen = Q2 - Q1 - 1;
                    }
                    break;
                case 'X':
                    Q1 = oprand.IndexOf('\'');
                    if (Q1 >= 0)
                    {
                        Q2 = oprand.IndexOf('\'', Q1 + 1);
                        if (Q2 > Q1)
                            nLen = (Q2 - Q1 - 1)/2;
                    }
                    break;

            }
            return nLen;
        }
        static void WriteThisLine()
        {
            if (IsCommentLine)
            {
                sw.WriteLine("{0,3:D} {1}", nlineNo, Line);
                Console.WriteLine("{0,3:D} {1}", nlineNo, Line);
            }

            else
            {
                string FormatLabel = string.Format("{0,-8}", Label);
                string FormatOpcode = string.Format("{0,-8}", Opcode);
                string FormatOprand = string.Format("{0,-8}", Oprand);

                sw.WriteLine("{0,3:D} {1:X4} {2}{3}{4}", nlineNo, Location, FormatLabel, FormatOpcode, FormatOprand);
                Console.WriteLine("{0,3:D} {1:X4} {2}{3}{4}", nlineNo, Location, FormatLabel, FormatOpcode, FormatOprand);
            }
        }
        static void WriteLastLine()
        {
            sw.WriteLine("{0,3:D}{1,17}", nlineNo, Opcode);
            Console.WriteLine("{0,3:D}{1,17}", nlineNo, Opcode);
        }
    }
}
已記錄
 

SimplePortal Classic 2.0.5