⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 plxanalyzer.cs

📁 本软件是针对PL/x语法结构设计的PL/x编译器
💻 CS
📖 第 1 页 / 共 3 页
字号:
using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;


namespace PLX
{

    class PLXAnalyzer
    {
        #region Error Message
        readonly int ER_EQL_NOT_BECOMES = 1;                                 //要用=,不能用:=       
        readonly int ER_ONLY_NUMBER = 2;                                         //必须给常量赋常数
        readonly int ER_ONLY_EQL = 3;                                                //这里必须是一个=
        readonly int ER_ONLY_IDIENT = 4;                                            //这里必须是一个标识符
        readonly int ER_MISS_COMMA_OR_SEMICOLON = 5;                //丢了一个分号或逗号
        readonly int ER_DECLARATION = 6;                                           //声明时出现了不正确的标识符
        readonly int ER_WAIT_STATEMENT = 7;                                     //等待一条语句
        readonly int ER_ID_REDUNDANCY = 8;                                       //标识符重复定义
        readonly int ER_NO_CONSTID = 9;                                            //不能调用常量标识符
        readonly int ER_INCORRECT_SYMBOL = 10;                              //语句里有不正确的符号                         
        readonly int ER_ID_NOTFOUND = 11;                                        //该标识符没有声明
        readonly int ER_TYPE_NOT_MATCH = 12;                                  //声明的类型与赋值的类型不匹配
        readonly int ER_ONLY_BECOMES = 13;                                     //赋值符是:=
        readonly int ER_FOLLOW_WRONG_SYMBOL = 14;                       //该语句跟着一个不正确的使用符号
        readonly int ER_ILLEGAL_CALL = 15;                                        //call常数或者变量是不允许的
        readonly int ER_WAIT_THEN = 16;                                            //等待then
        readonly int ER_WAIT_END = 17;                                              //等待end
        readonly int ER_WAIT_DO = 18;                                                //等待do
        readonly int ER_WAIT_UNTIL = 19;                                           //等待until
        readonly int ER_WAIT_RELATION_OPR = 20;                            //等待关系运算符
        readonly int ER_NO_PROCEDUREID = 21;                                 //表达式里不允许有过程标识符
        readonly int ER_MISS_LPAREN = 22;                                         //丢失左(
        readonly int ER_MISS_RPAREN = 23;                                         //丢失右)
        readonly int ER_MIN_ARRAY_LENGHT = 24;                               //数组的项数必须大于等于1
        readonly int ER_ARRAY_ITEMS_NOT_MATCH = 25;                     //数组的项数与声明时不符
        readonly int ER_EXCEED_BIT = 26;                                           //数字常量超过32位
        readonly int ER_MUST_NUMBER_OR_CONST = 27;                    //必须是数字或常量
        readonly int ER_MISS_LSQBRACKET = 28;                                //丢失左[
        readonly int ER_MISS_RSQBRACKET = 29;                                //丢失右]
        readonly int ER_MISS_LBGBRACKET = 30;                                //丢失左{
        readonly int ER_MISS_RBGBRACKET = 31;                                //丢失右}
        readonly int ER_ILLEGAL_ARRAY_INDEX = 32;                          //非法的数组索引
        readonly int ER_MUST_BEGINWITH_PROGRAM = 33;                 //程序必须以program开始
        readonly int ER_MUST_ENDWITH_DOT = 34;                             //程序必须以.结束
        readonly int ER_ONLY_LOGICAL_VAR_OR_CONST = 35;            //这里必须是一个逻辑变量或者常量
        readonly int ER_ONLY_INT_VAR_OR_CONST = 36;                    //这里必须是一个INTGER变量或者常量
        readonly int ER_WRONG_BEGINID_INTFACTOR = 37;               //算术表达式不能以此符号开始
        readonly int ER_WRONG_BEGINID_LOGICALFACTOR = 38;       //逻辑表达式不能以此符号开头
        readonly int ER_WRONG_BEGINID_OPRFACTOR = 39;             //关系表达式不能以此符号开头

        readonly string[] strErrorMsg = new string[]
            {
                "要用=,不能用:=" ,
                "必须给常量赋常数" ,
                "这里必须是一个=" ,
                "这里必须是一个标识符" ,
                "丢了一个分号或逗号" ,
                "声明时出现了不正确的标识符" ,
                "等待一条语句" ,
                "标识符重复定义" ,
                "不能调用常量标识符" ,
                "语句里有不正确的符号" ,
                "该标识符没有声明" ,
                "声明的类型与赋值的类型不匹配" ,
                "赋值符是:=" ,
                "该语句跟着一个不正确的使用符号" ,
                "call常数或者变量是不允许的" ,
                "等待then" ,
                "等待end" ,
                "等待do" ,
                "等待until" ,
                "等待关系运算符" ,
                "表达式里不允许有过程标识符" ,
                "丢失左(" ,
                "丢失右)" ,
                "数组的项数必须大于等于1" ,
                "数组的项数与声明时不符" ,
                "数字常量超过位" ,
                "必须是数字或常量" ,
                "丢失左[" ,
                "丢失右]" ,
                "丢失左{" ,
                "丢失右}" ,
                "非法的数组索引" ,
                "程序必须以program开始" ,
                "程序必须以.结束" ,
                "这里必须是一个逻辑变量或者常量" ,
                "这里必须是一个INTGER变量或者常量",
                "算术表达式不能以此符号开始",
                "逻辑表达式不能以此符号开始"
           };
        #endregion
        
        #region Const Definition
        const int NUM_OF_REAERVED_WORDS = 21;
        const int NUM_OF_OPR_WORDS = 17;
        const int LENGTH_OF_ID_TABLE = 100;
        const int MAX_NO_OF_DIGITS_IN_NUM = 32;
        const int LENGTH_OF_ID = 10;
        const int LEVMAX = 3;
        const int CXMAX = 200;                       //size of code array
        #endregion

        #region Private Attributes
        private int arraysize;
        private int codeIndex = 0;  
        private int tabIndex = 0;                      //Index of wordtab
        private int cc = 0, ll = 0,num;               //cc:character count, ll:line length, num:last number read 
        private int level;
        private int cx0;
        private string strCh = " ";                    //last character read
        private string strID;                             //last identifier read
        private string strSourceCode;
        private string strErrorOut;
        private string strMIDOut;
        private symbol sym;
                               
        #endregion

        #region Property
        public string StrSourceCode
        {
            get
            {
                return strSourceCode;
            }
            set
            {
                strSourceCode = value;
            }
        }

        public string StrErrorOut
        {
            get
            {
                return strErrorOut;
            }
            //set
            //{
            //    value = strErrorOut;
            //}

        }

        public string StrMIDOut
        {
            get
            {
                return strMIDOut;
            }
        }

        public int LL
        {
            get
            {
                return ll;
            }
            set
            {
                ll = value;
            }
        }

        public int CC
        {
            get
            {
                return cc;
            }
            set
            {
               cc = value;
            }
        }
               
        #endregion

        #region Symbol 
         public enum symbol
        {
            nul, ident, number, plus, minus, times, slash, mod, eql, neq, lss, leq, gtr, geq, lparen, rparen, lsqbracket, rsqbracket,
            lbgbracket, rbgbracket, comma, semicolon, period, becomes, progsym, procsym, intesym, logisym, constsym, callsym, ifsym, thensym,
            elsesym, whilesym, repeatsym, beginsym, endsym, orsym, andsym, notsym, truesym, falsesym, dosym, untilsym, writesym
        };

        string[] word = new string[NUM_OF_REAERVED_WORDS]{"and","begin","call","const","do","else","end","false","if","integer","logical","not","or","procedure","program",
                                                                                                    "repeat","then","true","until","while", "write"};

        symbol[] wsym = new symbol[NUM_OF_REAERVED_WORDS]{symbol.andsym,symbol.beginsym,symbol.callsym,symbol.constsym,symbol.dosym,symbol.elsesym,symbol.endsym,
                                                                                                        symbol.falsesym,symbol.ifsym,symbol.intesym,symbol.logisym,symbol.notsym,symbol.orsym,symbol.procsym,
                                                                                                        symbol.progsym,symbol.repeatsym,symbol.thensym,symbol.truesym,symbol.untilsym,symbol.whilesym,symbol.writesym};
        symbol[] ssym = new symbol[NUM_OF_OPR_WORDS] {symbol.plus,symbol.minus,symbol.times,symbol.slash,symbol.lparen,symbol.rparen,symbol.lsqbracket,symbol.rsqbracket,
                                                                                               symbol.lbgbracket,symbol.rbgbracket,symbol.eql, symbol.comma,symbol.semicolon,symbol.period,symbol.lss,symbol.gtr,symbol.mod};

        symbol[] dsbegsys = new symbol[] { symbol.intesym, symbol.logisym, symbol.procsym, symbol.constsym };

        symbol[] ssbegsys = new symbol[] { symbol.callsym, symbol.ifsym, symbol.whilesym, symbol.repeatsym, symbol.writesym };

        symbol[] afbegsys = new symbol[] { symbol.ident, symbol.number, symbol.lparen };

        symbol[] bfbegsys = new symbol[] { symbol.ident, symbol.truesym, symbol.falsesym, symbol.notsym, symbol.lparen,symbol.number};

        symbol[] dsfollsys = new symbol[] { symbol.intesym, symbol.logisym, symbol.procsym, symbol.constsym, symbol.semicolon };

        symbol[] ssfollsys = new symbol[] { symbol.callsym, symbol.ifsym, symbol.whilesym, symbol.repeatsym, symbol.writesym, symbol.semicolon, symbol.endsym, symbol.elsesym, symbol.untilsym };

        symbol[] aefollsys = new symbol[] { symbol.callsym, symbol.ifsym, symbol.whilesym, symbol.repeatsym, symbol.writesym, symbol.semicolon, symbol.endsym, symbol.minus, symbol.ident, symbol.number };

        symbol[] atfollsys = new symbol[] { symbol.callsym, symbol.ifsym, symbol.whilesym, symbol.repeatsym, symbol.writesym, symbol.semicolon, symbol.endsym, symbol.minus, symbol.ident, symbol.number, symbol.plus };

        symbol[] affollsys = new symbol[] { symbol.callsym, symbol.ifsym, symbol.whilesym, symbol.repeatsym, symbol.writesym, symbol.semicolon, symbol.endsym, symbol.minus, symbol.ident, symbol.number, symbol.plus, symbol.times, symbol.slash, symbol.mod, symbol.lparen };

        symbol[] befollsys = new symbol[] { symbol.ident, symbol.number, symbol.truesym, symbol.falsesym, symbol.notsym, symbol.lparen, symbol.semicolon, symbol.endsym, symbol.thensym, symbol.dosym };

        symbol[] btfollsys = new symbol[] { symbol.ident, symbol.number, symbol.truesym, symbol.falsesym, symbol.notsym, symbol.lparen, symbol.semicolon, symbol.endsym, symbol.thensym, symbol.dosym, symbol.orsym };

        symbol[] bffollsys = new symbol[] { symbol.ident, symbol.number, symbol.truesym, symbol.falsesym, symbol.notsym, symbol.lparen, symbol.semicolon, symbol.endsym, symbol.thensym, symbol.dosym, symbol.orsym, symbol.andsym };
       #endregion

        #region Other Definition
        public struct wordTab
        {
            public string name;
            public objekt kind;
            public int value;                               //constant:value;array:arraysize
            public int level;
            public int addr;                                //variable,procedure address
            public int size;                                 //reserve storage unit
        };

        wordTab[] wordtab = new wordTab[LENGTH_OF_ID_TABLE];
        //记录行号
        public static int lineNum;

        public enum objekt { integer, logical, procedure, constant, array };

        private string strSingleChPattern = @"[\+\-\*\/\[\]\{\}\(\)<>=.,;%]";

        int[] ssymAscii = new int[NUM_OF_OPR_WORDS] { '+', '-', '*', '/', '(', ')', '[', ']', '{', '}', '=', ',', ';', '.', '<', '>', '%' };
        #endregion

        #region Instruction
        public enum fct{lit,opr,lod,loa,sto,sta,cal,ini,jmp,jpc};

        public struct Instruction
        {
            public fct fct;
            public int level;
            public int address;
        };

        public Instruction[] code = new Instruction[CXMAX];


        #endregion

        public PLXAnalyzer() { }

        public void Error(int errorID)
        {
            strErrorOut += "Line " + lineNum + ": " + strErrorMsg[errorID - 1] + "\n";
        }

        public void GetSym()
        {
            while (AssistOpr.IsWhiteSpace(strCh))
                Getch();
            
            if (strCh == "\\")
            {
                HandleComment();
                while (AssistOpr.IsWhiteSpace(strCh))        //处理注释之后仍要处理whitespace
                    Getch();
            }

            if (Regex.IsMatch(strCh, "[A-Za-z]"))
            {
                HandleIDorReservedWords();
            }

            else if (Regex.IsMatch(strCh, "[0-9]"))
            {
                HandleConstantNumber();
            }

            else if (strCh == ":")
            {
                HandleAssignmentSym();
            }

            else if (strCh == "<")
            {
                HandleLssAndLeqSym();
            }

            else if (strCh == ">")
            {
                HandleGtrAndGeqSym();
            }

            else if (strCh == "/")
            {
                HandleNeqSym();
            }

            else if (Regex.IsMatch(strCh, strSingleChPattern))
            {
                HandleSingleCh();
            }
        }

        public void Getch()
        {
            if(cc != ll)
                strCh = strSourceCode.Substring(cc++, 1);
        }

        public void Test(symbol[] s1, symbol[] s2, int errorID)
        {
            if (!AssistOpr.IsContain<symbol>(s1, sym))
            {
                Error(errorID);
                if (s2 != null)
                {
                    while (!AssistOpr.IsContain<symbol>(s2, sym))
                        GetSym();
                }
            }
        }

        public string ListMidCode()
        {
            for(int i = 0; i < codeIndex ; i++)
                strMIDOut += i.ToString() + "\t" + code[i].fct + "\t" + code[i].level + "\t" + code[i].address + "\n";
            return StrMIDOut;
        }

        protected void Gen(fct x, int y, int z)
        {
            if (codeIndex > CXMAX)
            {
                strErrorOut = "程序过长!";
                return;
            }

            code[codeIndex].fct = x;
            code[codeIndex].level = y;
            code[codeIndex++].address = z;
        }

        protected void HandleComment()
        {
            do Getch();
            while (strCh != "\n");
        }

        protected void HandleIDorReservedWords()
        {
            int k = 0, i, j;
            StringBuilder strTempCh = new StringBuilder(LENGTH_OF_ID);
            do
            {
                strTempCh.Append(strCh);
                Getch();
            }
            while (Regex.IsMatch(strCh, "[A-Za-z0-9]"));

            strID = strTempCh.ToString();
            i = 0;
            j = NUM_OF_REAERVED_WORDS - 1;

            while (i <= j)
            {
                k = (i + j) / 2;
                int compResult = strID.CompareTo(word[k]);
                if (compResult == 0) break;
                else if (compResult < 0)
                    j = k - 1;
                else if (compResult > 0)
                    i = k + 1;
            }

            if (i <= j)
                sym = wsym[k];
            else
                sym = symbol.ident;
        }

        protected void HandleConstantNumber()
        {
            int k = 0;
            num = 0;
            sym = symbol.number;

            do
            {
                num = 10 * num + Convert.ToInt16(strCh);
                k += 1;
                Getch();
            }
            while (Regex.IsMatch(strCh, "[0-9]"));

            if (k > MAX_NO_OF_DIGITS_IN_NUM)
            {
                Error(ER_EXCEED_BIT);
            }
        }

        protected void HandleAssignmentSym()
        {
            Getch();
            if (strCh == "=")
            {
                sym = symbol.becomes;
                Getch();
            }
            else
            {
                sym = symbol.nul;
            }
        }

        protected void HandleLssAndLeqSym()
        {
            Getch();
            if (strCh == "=")
            {
                sym = symbol.leq;
                Getch();
            }

            else
            {
                sym = symbol.lss;
            }
        }

        protected void HandleGtrAndGeqSym()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -