可视化SNL词法分析器

来源:互联网 发布:淘宝店铺亲戚过户 编辑:程序博客网 时间:2024/05/16 14:43

可视化SNL词法分析器下载: http://download1.csdn.net/down3/20070514/14193920683.exeSuper SNL analyzation

代码:

窗体设计代码

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Collections.Generic;

namespace snl
{
    /// <summary>
    /// Form1 的摘要说明。
    /// </summary>
    public class Form1 : System.Windows.Forms.Form
    {
        private System.Windows.Forms.MainMenu mainMenu1;
        private System.Windows.Forms.GroupBox groupBox1;
        private System.Windows.Forms.RichTextBox result;
        private System.Windows.Forms.OpenFileDialog openFileDialog1;
        private System.Windows.Forms.MenuItem filemune;
        private System.Windows.Forms.MenuItem open;
        private System.Windows.Forms.MenuItem save;
        private System.Windows.Forms.MenuItem saveas;
        private System.Windows.Forms.MenuItem quit;
        private System.Windows.Forms.MenuItem operation;
        private System.Windows.Forms.MenuItem analyze;
        private System.Windows.Forms.MenuItem saveresult;
        private IContainer components;
        private SaveFileDialog saveFileDialog1;
        //文件路径
        private string path = "";
        //文件内容
        private string fileContents = "";
        private MenuItem clearText;
        private GroupBox groupBox2;
        private RichTextBox file;
        //关闭标志
        private bool closeFlag = false;      

        public Form1()
        {
            //
            // Windows 窗体设计器支持所必需的
            //
            InitializeComponent();

            //
            // TODO: 在 InitializeComponent 调用后添加任何构造函数代码
            //
        }

        /// <summary>
        /// 清理所有正在使用的资源。
        /// </summary>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose(disposing);
        }

        #region Windows 窗体设计器生成的代码
        /// <summary>
        /// 设计器支持所需的方法 - 不要使用代码编辑器修改
        /// 此方法的内容。
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
            this.mainMenu1 = new System.Windows.Forms.MainMenu(this.components);
            this.filemune = new System.Windows.Forms.MenuItem();
            this.open = new System.Windows.Forms.MenuItem();
            this.clearText = new System.Windows.Forms.MenuItem();
            this.save = new System.Windows.Forms.MenuItem();
            this.saveas = new System.Windows.Forms.MenuItem();
            this.quit = new System.Windows.Forms.MenuItem();
            this.operation = new System.Windows.Forms.MenuItem();
            this.analyze = new System.Windows.Forms.MenuItem();
            this.saveresult = new System.Windows.Forms.MenuItem();
            this.groupBox1 = new System.Windows.Forms.GroupBox();
            this.result = new System.Windows.Forms.RichTextBox();
            this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
            this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog();
            this.groupBox2 = new System.Windows.Forms.GroupBox();
            this.file = new System.Windows.Forms.RichTextBox();
            this.groupBox1.SuspendLayout();
            this.groupBox2.SuspendLayout();
            this.SuspendLayout();
            //
            // mainMenu1
            //
            this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.filemune,
            this.operation});
            //
            // filemune
            //
            this.filemune.Index = 0;
            this.filemune.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.open,
            this.clearText,
            this.save,
            this.saveas,
            this.quit});
            this.filemune.Text = "文件";
            //
            // open
            //
            this.open.Index = 0;
            this.open.Shortcut = System.Windows.Forms.Shortcut.CtrlO;
            this.open.Text = "打开";
            this.open.Click += new System.EventHandler(this.open_Click);
            //
            // clearText
            //
            this.clearText.Index = 1;
            this.clearText.Shortcut = System.Windows.Forms.Shortcut.CtrlR;
            this.clearText.Text = "清空";
            this.clearText.Click += new System.EventHandler(this.clearText_Click);
            //
            // save
            //
            this.save.Index = 2;
            this.save.Shortcut = System.Windows.Forms.Shortcut.CtrlS;
            this.save.Text = "保存";
            this.save.Click += new System.EventHandler(this.save_Click);
            //
            // saveas
            //
            this.saveas.Index = 3;
            this.saveas.Shortcut = System.Windows.Forms.Shortcut.CtrlShiftS;
            this.saveas.Text = "另存为";
            this.saveas.Click += new System.EventHandler(this.saveas_Click);
            //
            // quit
            //
            this.quit.Index = 4;
            this.quit.Shortcut = System.Windows.Forms.Shortcut.CtrlQ;
            this.quit.Text = "退出";
            this.quit.Click += new System.EventHandler(this.quit_Click);
            //
            // operation
            //
            this.operation.Index = 1;
            this.operation.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.analyze,
            this.saveresult});
            this.operation.Text = "调试";
            //
            // analyze
            //
            this.analyze.Index = 0;
            this.analyze.Shortcut = System.Windows.Forms.Shortcut.F5;
            this.analyze.Text = "词法分析";
            this.analyze.Click += new System.EventHandler(this.analyze_Click);
            //
            // saveresult
            //
            this.saveresult.Index = 1;
            this.saveresult.Shortcut = System.Windows.Forms.Shortcut.CtrlShiftR;
            this.saveresult.Text = "保存分析结果";
            this.saveresult.Click += new System.EventHandler(this.saveresult_Click);
            //
            // groupBox1
            //
            this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.groupBox1.Controls.Add(this.result);
            this.groupBox1.Location = new System.Drawing.Point(0, 200);
            this.groupBox1.Name = "groupBox1";
            this.groupBox1.Size = new System.Drawing.Size(488, 192);
            this.groupBox1.TabIndex = 1;
            this.groupBox1.TabStop = false;
            this.groupBox1.Text = "分析结果";
            //
            // result
            //
            this.result.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                        | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.result.Location = new System.Drawing.Point(8, 13);
            this.result.Name = "result";
            this.result.ReadOnly = true;
            this.result.Size = new System.Drawing.Size(475, 171);
            this.result.TabIndex = 2;
            this.result.Text = "";
            //
            // openFileDialog1
            //
            this.openFileDialog1.Filter = "SNL文件(*.snl)|*.snl|文本文件(*.txt)|*.txt|所有文件(*.*)|*.*";
            this.openFileDialog1.Title = "请选择你想要打开的文件";
            //
            // saveFileDialog1
            //
            this.saveFileDialog1.Filter = "SNL文件(*.snl)|*.snl|文本文件(*.txt)|*.txt";
            this.saveFileDialog1.Title = "选择你要保存的文件类型";
            //
            // groupBox2
            //
            this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                        | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.groupBox2.Controls.Add(this.file);
            this.groupBox2.Location = new System.Drawing.Point(0, 4);
            this.groupBox2.Name = "groupBox2";
            this.groupBox2.Size = new System.Drawing.Size(489, 190);
            this.groupBox2.TabIndex = 3;
            this.groupBox2.TabStop = false;
            this.groupBox2.Text = "待分析代码";
            //
            // file
            //
            this.file.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                        | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.file.AutoWordSelection = true;
            this.file.BackColor = System.Drawing.Color.WhiteSmoke;
            this.file.Location = new System.Drawing.Point(6, 12);
            this.file.Name = "file";
            this.file.Size = new System.Drawing.Size(477, 167);
            this.file.TabIndex = 2;
            this.file.Text = "";
            this.file.WordWrap = false;
            //
            // Form1
            //
            this.AllowDrop = true;
            this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
            this.ClientSize = new System.Drawing.Size(488, 401);
            this.Controls.Add(this.groupBox2);
            this.Controls.Add(this.groupBox1);
            this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
            this.Menu = this.mainMenu1;
            this.Name = "Form1";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.Text = "Super SNL analyzation";
            this.DragDrop += new System.Windows.Forms.DragEventHandler(this.Form1_DragDrop);
            this.Closing += new System.ComponentModel.CancelEventHandler(this.Form1_Closing);
            this.DragEnter += new System.Windows.Forms.DragEventHandler(this.Form1_DragEnter);
            this.Load += new System.EventHandler(this.Form1_Load);
            this.groupBox1.ResumeLayout(false);
            this.groupBox2.ResumeLayout(false);
            this.ResumeLayout(false);

        }
        #endregion

        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.Run(new Form1());
        }

        private void Form1_Load(object sender, System.EventArgs e)
        {
            MessageBox.Show("/t感谢您使用Super SNL analyzation软件!/t/n您的支持是我们前进的动力!");           
        }

        // <summary>
        // 关闭窗口时调用
        // </summary>
        private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            //判断是否从菜单关闭
            if (!closeFlag)
                if (!closeForm())
                    e.Cancel = true;
        }

       /*
        private void Form1_Closed(object sender, System.EventArgs e)
        {
        }
        */

        private void Form1_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.Link;
                file.ReadOnly = true;
            }
            else e.Effect = DragDropEffects.None;
        }

        private void Form1_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
        {            
            path = ((System.Array)e.Data.GetData(DataFormats.FileDrop)).GetValue(0).ToString();
            openFile(path);
            file.ReadOnly = false;
        }

        // <summary>
        // 保存为新文件
        // </summary>
        private bool saveNewFile(string resultOrFile)
        {
            //不允许保存空文件
            if (resultOrFile != "")
            {
                //显示文件保存对话框
                saveFileDialog1.ShowDialog();
                //获取新文件路径
                string savePath = saveFileDialog1.FileName;
                // 路径非空时保存文件
                if (savePath != "")
                {
                    try
                    {
                        //直接写入源文件
                        File.WriteAllText(savePath, resultOrFile, System.Text.Encoding.GetEncoding("GB2312"));
                        //产生源文件副本
                        fileContents = resultOrFile;
                        //返回文件保存成功
                        return true;
                        //MessageBox.Show("文件保存成功!");
                    }
                    catch (Exception saveFileException)
                    {
                        MessageBox.Show("文件保存失败,请稍后重试!");
                    }
                }
            }
            return false;
        }

        // <summary>
        // 保存文件
        // </summary>
        private bool saveFile()
        {
            // 路径非空时保存文件
            if (path != "")
            {
                try
                {
                    //直接写入源文件
                    File.WriteAllText(path, file.Text, System.Text.Encoding.GetEncoding("GB2312"));
                    //产生源文件副本
                    fileContents = file.Text;
                    //返回文件保存成功
                    return true;
                    //MessageBox.Show("文件保存成功!");
                }
                catch (Exception fileSaveException)
                {
                    MessageBox.Show("源文件不存在或其他程序正在使用,请确认后重试!");
                }
            }
            return saveNewFile(file.Text);
        }

        // <summary>
        // 关闭窗口
        // </summary>
        private bool closeForm()
        {
            //判断文件是否修改后没有被保存,即文件是否允许直接关闭
            if (fileContents == file.Text)
            {
                return true;
            }
            else
            {
                DialogResult saveOrNot;
                saveOrNot = MessageBox.Show("文件已修改,是否保存?", "文件保存", MessageBoxButtons.YesNoCancel);
                if (saveOrNot.Equals(DialogResult.Yes))
                {
                    if (saveFile())
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
                else if (saveOrNot.Equals(DialogResult.No))
                {
                    return true;
                }
            }
            return false;
        }

    // <summary>
        // 设置错误行颜色
        // </summary>       
        private void setErrorLineColor(Queue<int> errorLines)
        {
            //恢复文本颜色
            file.SelectAll();
            file.SelectionColor = System.Drawing.Color.Black;
            file.Select(0, 0);  
            //错误过多时提示
            if (errorLines.Count == file.Lines.Length)
            {
                MessageBox.Show("请确认你分析的代码是合法的SNL代码!");
                return;
            }                    
            while(errorLines.Count > 0)               
            {
                 //记录出现错误的当前行
                int curLine = errorLines.Dequeue() - 1;
                file.Select(file.Text.IndexOf(file.Lines[curLine]), file.Lines[curLine].Length);
                file.SelectionColor = System.Drawing.Color.Red;
                file.Select(0,0);
            }
        }

        // <summary>
        // 文件打开函数
        // </summary>
        private bool checkFileExtension(string fileName)
        {
            String[] fileExtension = new String[] { ".txt", ".snl", ".log", ".ini", ".html", ".xml", ".htm", ".jsp", ".c", ".cpp", ".java", ".h", ".cs", ".css", ".aspx", ".config" };
            FileInfo fileInfo = new FileInfo(fileName);
            //MessageBox.Show(fileInfo.Extension+"源文件不存在或文件类型不匹配,请确认后再重试!");
            foreach(string name in fileExtension)
            {
                if(fileInfo.Extension.ToLower().EndsWith(name))
                return true;
            }
            return false;
          
        }

        // <summary>
        // 文件打开函数
        // </summary>
        private void openFile(string path)
        {
            if (checkFileExtension(path))
            {
                try
                {
                    StreamReader content = new StreamReader(path, System.Text.Encoding.GetEncoding("GB2312"));
                    file.Text = content.ReadToEnd();
                    fileContents = file.Text;
                    content.Close();
                }
                catch (Exception pathIsError)
                {
                    MessageBox.Show("源文件不存在或文件类型不匹配,请确认后重试!");
                }
            }
            else
            {
                MessageBox.Show("文件类型不匹配,本编译器仅支持纯文本文件和SNL文件,请确认后重试!");
            }
        }
        // <summary>
        // 点击"打开"按钮时,触发事件
        // </summary>       
        private void open_Click(object sender, System.EventArgs e)
        {
            openFileDialog1.ShowDialog();
            path = openFileDialog1.FileName;
            if (path != "")
            {
                openFile(path);
            }
        }

        // <summary>
        // 点击"清空"按钮时,触发事件
        // </summary>
        private void clearText_Click(object sender, System.EventArgs e)
        {
            file.Text = "";
        }

        // <summary>
        // 点击"保存"按钮时,触发事件
        // </summary>       
        private void save_Click(object sender, System.EventArgs e)
        {
            saveFile();
        }

        // <summary>
        // 点击"另存为"按钮时,触发事件
        // </summary>
        private void saveas_Click(object sender, System.EventArgs e)
        {
            saveNewFile(file.Text);
        }

        // <summary>
        // 点击"退出"按钮时,触发事件
        // </summary>
        private void quit_Click(object sender, System.EventArgs e)
        {
            if (closeForm())
            {
                closeFlag = true;
                this.Close();
            }
        }

        // <summary>
        // 点击"词法分析"按钮时,触发事件
        // </summary>
        private void analyze_Click(object sender, System.EventArgs e)
        {
            //当文本框非空时执行
            if (file.Text != "")
            {
                analyzer resultString = new analyzer(file.Text.ToString());
                result.Text = resultString.printTokenList();
                setErrorLineColor(resultString.getErrorLines());
            }
        }

        // <summary>
        // 点击"保存分析结果"按钮时,触发事件
        // </summary>
        private void saveresult_Click(object sender, System.EventArgs e)
        {
            saveNewFile(result.Text);
        }
    }
}

using System;
using System.Collections.Generic;
using System.Text;

namespace snl
{
    class ReservedWord
    {
        /*
        * 保留字类,为保留字单独设置一个类,包含了自身的类型,
        * 和名字
        */
        private int lexType;
        private String name;
        public ReservedWord(String name, int lexType)
        {
            this.lexType = lexType;
            this.name = name;
        }
        /*
         * 获取类型信息
         */
        public int getLexType()
        {
            return lexType;
        }
        /*
         * 设置类型信息
         */
        public void setLexType(int lex)
        {
            this.lexType = lex;
        }
        /*
         * 获取保留字的名字
         */
        public String getName()
        {
            return name;
        }
        /*
         * 设置保留字的名字
         */
        public void setName(String name)
        {
            this.name = name;
        }
    }
}

using System;
using System.Collections.Generic;
using System.Text;

namespace snl
{
    class LexType
    {
        /*
 * 定义了Token的各种类型常量
 */

        public const int ENDFILE = -1;
        public const int ERROR = -2;
        public const int PROGRAM = -3;
        public const int PROCEDURE = -4;
        public const int TYPE = -5;
        public const int VAR = -6;
        public const int IF = -7;
        public const int THEN = -8;
        public const int ELSE = -9;
        public const int FI = -10;
        public const int DO = -11;
        public const int WHILE = -12;
        public const int ENDWH = -13;
        public const int BEGIN = -14;
        public const int END = -15;
        public const int READ = -16;
        public const int WRITE = -17;
        public const int ARRAY = -18;
        public const int OF = -19;
        public const int RECORD = -20;
        public const int RETURN = -21;
        public const int INTEGER = -22;
        public const int CHAR = -23;
        public const int ID = -24;
        public const int INTC = -25;
        public const int CHARC = -26;
        public const int ASSIGN = -27;
        public const int EQ = -28;
        public const int LT = -29;
        public const int GT = -30;
        public const int PLUS = -31;
        public const int MINUS = -32;
        public const int TIMES = -33;
        public const int OVER = -34;
        public const int LPAREN = -35;
        public const int RPAREN = -36;
        public const int DOT = -37;
        public const int COLON = -38;
        public const int SEMI = -39;
        public const int COMMA = -40;
        public const int LMIDPAREN = -41;
        public const int RMIDPAREN = -42;
        public const int UNDERANGE = -43;
    }
}

 

using System;
using System.Collections.Generic;
using System.Text;

namespace snl
{
    class Token
    {

        /*
 * Token类,定义了该Token所在的行标,类型以及单词信息
 */
      
            private int lineNum;
            private int lex;
            private String sem;
            /*
             * 默认构造函数
             */
            public Token()
            {
                sem = "";
            }
            /*
             * 获取类型信息
             */
            public int getLex()
            {
                return lex;
            }
            /*
             * 设置类型信息
             */
            public void setLex(int lex)
            {
                this.lex = lex;
            }
            /*
             * 获取token所在的行标
             */
            public int getLineNum()
            {
                return lineNum;
            }
            /*
             * 设置Token所在的行标
             */
            public void setLineNum(int lineNum)
            {
                this.lineNum = lineNum;
            }
            /*
             * 获取Token的单词信息
             */
            public String getSem()
            {
                return sem;
            }
            /*
             * 设置Token的单词信息
             */
            public void setSem(String sem)
            {
                this.sem = sem;
            }
        }   
}

 

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Collections;
using System.Windows.Forms;

namespace snl
{
    class analyzer
    {
        //文件结尾标示
        private const int EOF = -1;
        //字符输入流
        private StringReader reader;
        //记录生成的Token序列
        private Queue<Token> tokenList;
        //记录分析结果
        private string output = "";
        //记录分行读入的字符串
        private string lineBuf;
        //记录行,列位置
        private int lineNum, linePos;
        //记录错误信息
        private ErrorList errorList;
        private Queue<int> errorLines = new Queue<int>();
        //记录当前处理单词的Token
        private Token curToken = new Token();
        //记录当前处理的单词
        private String buf = "";
        //保留字列表
        private ReservedWord[] reservedWord = new ReservedWord[] {
           new ReservedWord("program", LexType.PROGRAM),
           new ReservedWord("type", LexType.TYPE),
           new ReservedWord("var", LexType.VAR),
           new ReservedWord("procedure", LexType.PROCEDURE),
           new ReservedWord("begin", LexType.BEGIN),
           new ReservedWord("end", LexType.END),
           new ReservedWord("array", LexType.ARRAY),
           new ReservedWord("of", LexType.OF),
           new ReservedWord("record", LexType.RECORD),
           new ReservedWord("if", LexType.IF),
           new ReservedWord("then", LexType.THEN),
           new ReservedWord("else", LexType.ELSE),
           new ReservedWord("fi", LexType.FI),
           new ReservedWord("while", LexType.WHILE),
           new ReservedWord("do", LexType.DO),
           new ReservedWord("endwh", LexType.ENDWH),
           new ReservedWord("read", LexType.READ),
           new ReservedWord("write", LexType.WRITE),
           new ReservedWord("return", LexType.RETURN),
           new ReservedWord("integer", LexType.INTEGER),
           new ReservedWord("char", LexType.CHAR) };

        /*
         * 输出 词法分析的结果以及错误信息的实例
         */
        public analyzer(string input)
        {
            //初始化输入流,Token序列记录表,错误纪录表
            reader = new StringReader(input);
            tokenList = new Queue<Token>();
            errorList = new ErrorList();
            try
            {
                //读入第一行
                lineBuf = reader.ReadLine();
            }
            catch (IOException e)
            {
                Console.WriteLine(e.StackTrace.ToString());              
            }
            //行尾标示符处理
            lineBuf += '/n';
            //初始化行号
            lineNum = 1;
            //初始化列号
            linePos = 0;
        }

        /*
         * 判断是否是数字或者字母
         */
        private bool isLetterOrDigit(int charInt)
        {
            if (isLetter(charInt) | isDigit(charInt))
                return true;
            return false;
        }

        /*
         * 判断是否是数字
         */
        private bool isDigit(int charInt)
        {
            char ch = (char)charInt;
            if ('0' <= ch && ch <= '9')
                return true;
            return false;
        }

        /*
         * 判断是否是字母
         */
        private bool isLetter(int charInt)
        {
            char ch = (char)charInt;
            if (('A' <= ch && ch <= 'Z') | ('a' <= ch && ch <= 'z'))
                return true;
            return false;
        }

        /*
        * 扫描函数,形成一个token
        */
        protected Token scan()
        {
            //初始化curToken & buf
            curToken = new Token();
            buf = "";
            //开始处理下一个单词
            processStartState();
            //设置Token单词信息
            curToken.setSem(buf);
            //判别单词是否为保留字
            if (curToken.getLex() == LexType.ID)
                curToken.setLex(reservedLookup(curToken.getSem()));
            //设置Token序列行号
            curToken.setLineNum(lineNum);
            return curToken;
        }

        /*
        * 读取下一个单词
        */
        protected int getNextChar()
        {
            //判断是否为文件尾
            if (lineBuf == null)
                return EOF;
            //判断是否为行尾
            if (linePos >= lineBuf.Length)
            {
                try
                {
                    lineBuf = reader.ReadLine();
                    //判断是否为文件尾
                    if (lineBuf == null)
                        return EOF;
                    else
                    {
                        //行尾标示符处理
                        lineBuf += '/n';                      
                        //初始化列号
                        linePos = 0;
                        //下移一行
                        lineNum++;
                    }
                }
                catch (IOException e)
                {
                    Console.WriteLine( e.StackTrace);
                }
            }
            return lineBuf[linePos++];
        }

        /*
         * 回退一个字符
         */
        protected void unGetNextChar()
        {
            linePos--;
        }

        /*
        * 处理开始状态,根据读入的第一个字母决定下一个要处理的状态
        */
        private void processStartState()
        {
            int c = getNextChar();
            if (isDigit(c))
            {
                buf += (char)c;
                //处理并识别数字
                processNumState();
            }
            else if (isLetter(c))
            {
                buf += (char)c;
                //处理ID
                processIDState();
            }
            else if (c == ':')
            {
                buf += (char)c;
                //处理并识别赋值符号
                processAssignState();
            }
            else if (c == '.')
            {
                buf += (char)c;
                //处理并识别数组下标
                processRangeState();
            }
            else if (c == '/'')
            {
                buf += (char)c;
                //处理并识别单个字符
                processCharState();
            }
            else if (c == '{')
                //处理注释
                processCommentState();
            else if (c == ' ' || c == '/t' || c == '/n')
            {
                //完成状态,处理下一个单词
                processStartState();
            }
            else
            {
                //处理并识别单字符分界符
                switch (c)
                {
                    case EOF:
                        curToken.setLex(LexType.ENDFILE);
                        buf += (char)c;
                        break;
                    case '=':
                        curToken.setLex(LexType.EQ);
                        buf += (char)c;
                        break;
                    case '<':
                        curToken.setLex(LexType.LT);
                        buf += (char)c;
                        break;
                    case '>':
                        curToken.setLex(LexType.GT);
                        buf += (char)c;
                        break;
                    case '+':
                        curToken.setLex(LexType.PLUS);
                        buf += (char)c;
                        break;
                    case '-':
                        curToken.setLex(LexType.MINUS);
                        buf += (char)c;
                        break;
                    case '*':
                        curToken.setLex(LexType.TIMES);
                        buf += (char)c;
                        break;
                    case '/':
                        curToken.setLex(LexType.OVER);
                        buf += (char)c;
                        break;
                    case '(':
                        curToken.setLex(LexType.LPAREN);
                        buf += (char)c;
                        break;
                    case ')':
                        curToken.setLex(LexType.RPAREN);
                        buf += (char)c;
                        break;
                    case ';':
                        curToken.setLex(LexType.SEMI);
                        buf += (char)c;
                        break;
                    case ',':
                        curToken.setLex(LexType.COMMA);
                        buf += (char)c;
                        break;
                    case '[':
                        curToken.setLex(LexType.LMIDPAREN);
                        buf += (char)c;
                        break;
                    case ']':
                        curToken.setLex(LexType.RMIDPAREN);
                        buf += (char)c;
                        break;
                    default:
                        //处理错误
                        curToken.setLex(LexType.ERROR);
                        buf += "The " + linePos + " Character '" + (char)c + "' is error !";
                        errorList.addError(new Error("Unexpected charactor: "
                          + (char)c, lineNum));
                        break;
                }
            }
        }

        /*
        * 查询一个标识符是否为保留字类,如果是则返回类型该保留字的 类型,否则返回ID类型
        */
        protected int reservedLookup(String reserved)
        {
            for (int i = 0; i < reservedWord.Length; i++)
            {
                if (reservedWord[i].getName().Equals(reserved))
                    return reservedWord[i].getLexType();
            }
            return LexType.ID;
        }

        /*
        * 处理并识别赋值:=单词
        */
        protected void processAssignState()
        {
            int c = getNextChar();
            if (c == '=')
            {
                curToken.setLex(LexType.ASSIGN);
                buf += (char)c;
            }
            else
            {
                //处理错误
                curToken.setLex(LexType.ERROR);
                buf += "The " + linePos + " Character '" + (char)c + "' is error !";
                errorList.addError(new Error("Unexpected charactor: " + (char)c,
                  lineNum));
                unGetNextChar();
            }
        }

        /*
         * 处理并识别注释{...}单词
         */
        protected void processCommentState()
        {
            int c = getNextChar();
            while (c != '}')
            {
                if (c == EOF)
                {
                    //处理错误
                    curToken.setLex(LexType.ERROR);
                    buf += "You should end commentary with '}'!";
                    errorList.addError(new Error("Through to the end of program,you lost a '}' to finish commentary !",
                      lineNum));
                    return;
                }
                c = getNextChar();
            }
            processStartState();
        }

        /*
         * 处理并识别数组下标中(子介)..单词
         */
        protected void processRangeState()
        {
            int c = getNextChar();
            if (c == '.')
            {
                curToken.setLex(LexType.UNDERANGE);
                buf += (char)c;
            }
            else
            {
                curToken.setLex(LexType.DOT);
                unGetNextChar();
            }
        }

        /*
         * 处理并识别单个字符
         */
        protected void processCharState()
        {
            int c = getNextChar();
            if (isLetterOrDigit(c))
            {
                int c1 = getNextChar();
                if (c1 == '/'')
                {
                    curToken.setLex(LexType.CHARC);
                    buf += (char)c;
                    buf += (char)c1;
                }
                else
                {
                    unGetNextChar();
                    unGetNextChar();
                    //处理错误
                    curToken.setLex(LexType.ERROR);
                    buf += "The " + linePos + " Character '" + (char)c + "' is error !";
                    errorList.addError(new Error("Unexpect charactor: " + (char)c,
                      lineNum));
                }
            }
            else
            {
                unGetNextChar();
                //处理错误
                curToken.setLex(LexType.ERROR);
                buf += "The " + linePos + " Character '" + (char)c + "' is error !";
                errorList.addError(new Error("Unexpected charactor: " + (char)c,
                  lineNum));
            }
        }

        /*
         * 处理并识别标识符ID单词
         */
        protected void processIDState()
        {
            int c = getNextChar();
            while (isLetterOrDigit(c))
            {
                buf += (char)c;
                c = getNextChar();
            }
            unGetNextChar();
            curToken.setLex(LexType.ID);
        }

        /*
         * 处理并识别数字num单词
         */
        public void processNumState()
        {
            int c = getNextChar();
            if (isDigit(c))
            {
                buf += (char)c;
                c = getNextChar();
            }
            unGetNextChar();
            curToken.setLex(LexType.INTC);
        }

        /*
         * 产生词法分析的Token序列
         */
        public void genTokenList()
        {
            Token token = scan();
            while (token.getLex() != LexType.ENDFILE)
            {
                tokenList.Enqueue(token);
                token = scan();
            }
            tokenList.Enqueue(token);
        }

        /*
        * 打印错误信息
        */
        private void printErrorInfo()
        {
            //产生词法分析的Token序列
            genTokenList();           
            int errorNum = errorList.getErrorNum(),flag=0;
            if (errorNum == 0)
                output += "Perfect Program ! There is no morphology errer !/n";
            else
            {
                if (errorNum == 1)
                    output += "After morphology analyze,there is only one error :/n";
                else
                    output += "After morphology analyze,there are :" + errorNum + " errors:/n";
                Queue<Error> errors = errorList.getErrors();
                for (int i = 0; i < errorNum; i++)
                {
                    flag=errors.Peek().getLineNum();
                    output += "Error(" + (i + 1) + ") in line "
                      + flag + ": "
                      + errors.Peek().getErrorInfo() + " ;/n";
                    if (!errorLines.Contains(flag))
                    {
                        errorLines.Enqueue(flag);
                    }
                    errors.Dequeue();
                }
            }
        }

        /*
         * 打印token序列
         */
        public string printTokenList()
        {
            //调用错误处理和Token序列产生函数
            printErrorInfo();
            //获得Token序列项数
            int count = tokenList.Count;
            //遍历tokenList
            for (int i = 0; i < count; i++)
            {
                Token curToken = tokenList.Dequeue();
                output += curToken.getLineNum() + ": ";
                switch (curToken.getLex())
                {
                    case LexType.ASSIGN:
                    case LexType.EQ:
                    case LexType.LT:
                    case LexType.GT:
                    case LexType.PLUS:
                    case LexType.MINUS:
                    case LexType.TIMES:
                    case LexType.OVER:
                    case LexType.LPAREN:
                    case LexType.RPAREN:
                    case LexType.DOT:
                    case LexType.COMMA:
                    case LexType.SEMI:
                    case LexType.LMIDPAREN:
                    case LexType.RMIDPAREN:
                    case LexType.UNDERANGE:
                        output += curToken.getSem() + "/n";
                        break;
                    case LexType.ID:
                        output += "ID, name = " + curToken.getSem()
                          + "/n";
                        break;
                    case LexType.INTC:
                        output += "INTC, value = " + curToken.getSem()
                          + "/n";
                        break;
                    case LexType.ENDFILE:
                        output += "EOF/n";
                        break;
                    case LexType.ERROR:
                        output += "EORR: " + curToken.getSem() + "/n";
                        break;
                    default:
                        output += "Resered word: " + curToken.getSem()
                          + "/n";
                        break;
                }
            }
            return output;
        }
        /*
         * 获取错误列表
         */
        public Queue<int> getErrorLines()
        {
            return errorLines;
        }
    }
}

 

using System;
using System.Collections.Generic;
using System.Text;

namespace snl
{
    class Error
    {
        /*
        * Error类定义了整个SNLCompiler中错误的显示信息
        * 以及出现错误所在的行,便于错误的统一管理。
        */

        private String errorInfo;
        private int lineNum;        
        /*
         * 使用一个类型为String表示信息,一个int表示出现错误的行来 创建一个错误实例
         */
        public Error(String errorInfo, int lineNum)
        {
            this.errorInfo = errorInfo;
            this.lineNum = lineNum;           
        }
        /*
         * 获取错误的信息
         */
        public String getErrorInfo()
        {
            return errorInfo;
        }
        /*
         * 获取错误出现的行标
         */
        public int getLineNum()
        {
            return lineNum;
        }           
    }
}

 

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace snl
{
    class ErrorList
    {
        /*
         * ErrorList主要是保存在各个过程中出现的错误
         * 可能会带了一定的内存开销,在实用的编译器中并不可取
         */

        private Queue<Error> errorList;//=new Queue ;

        /*
         * 默认的构造函数
         */
        public ErrorList()
        {
            errorList = new Queue<Error>();
        }
        /*
         * 向错误列表中添加错误信息
         */
        public void addError(Error err)
        {
            errorList.Enqueue(err);
        }
        /*
         * 获取错误列表
         */
        public Queue<Error> getErrors()
        {
            return errorList;
        }
        public void clearError()
        {
            errorList.Clear();
        }
        /*
         * 打印错误信息
         */
        public void printErrors(string errorString)
        {
            for (int i = 0; i < errorList.Count; i++)
            {
                errorString += "Error " + (i + 1) + " in line "
                             + (errorList.Peek().getLineNum()) + ": "
                             + errorList.Peek().getErrorInfo() + " ;";
                errorList.Dequeue();
            }
        }
        /*
         * 获取错误的数目
         */
        public int getErrorNum()
        {
            return errorList.Count;
        }
    }
}

原创粉丝点击