编译原理实验(一)之词法分析

版权声明:本文为博主原创文章,纯粹自娱。 https://blog.csdn.net/moakun/article/details/86411814

词法分析

(1)参考附录1设计一个简单语言的词法分析程序,要求能够处理注释、换行回车、部分复合运算符(如>=)。

(2)设计并实现含多条简单赋值语句的语法分析程序,要求有一定的出错提示与错误恢复功能。    (参考附录2)

附录1:

例C源程序段:
main() 
{
    int  A,B,C,D;  /*类型说明*/ 
   A=2; B=4; C=10; D=100;
   while (A<C  and B<D)
   {  
       if (A==1) C=C-1;
      else    while (A<D)
             {A=A+2;}   
   }
}

 

附录2:

a=2; b=4; 
c=c-1;
area=3.14*a*a;
s= 2*3.1416*r*(h+r);

实验代码

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace WordPicker {
    /// <summary>
    /// 词
    /// </summary>
    struct Word {
        public int typeNum;
        public string word;
        public override string ToString() {
            return "(" + typeNum + "," + word + ")";
        }
        public string ToShow() {
            return typeNum + "," + word;
        }
    }

    class WordPicker {
      
        string input = "";
        int input_index = 0;
        char character;
        /// <summary>
        /// 关键字表
        /// </summary>
        string[] keyWordTable = {
            "auto","break","case", "char","const",
            "continue","default","do","double",
            "else","enum","extern","float","for",
            "goto","if", "int","long", "register",
            "return","short","signed","sizeof","static",
            "struct","switch","typedef","union","unsigned",
            "void","volatile","while"};
        /// <summary>
        /// 操作符表
        /// </summary>
        string[] operatorTable = {
            "{","}","(",")","[","]","->",".",
            "++","--",
            "&&","||","!",
            "~","&","|","^",
            "+","-","*","%","/",
            "<<",">>",
            "<",">",">=","<=",
            "==","!=","?",":",",",";",
            "=","+=","-=","*=","/=","%=",
            "&=","^=","|=",">>=","<<="
        };

        string[] operatorSort = null;
        int wordTypeNumber;    //变量名类型
        int numberTypeNumber;  //数值类型
        int charTypeNumber;    //字符类型
        int stringTypeNumber;    //字符串类型
        int endTypeNumber = -1;  //结束符类型
        int errorTypeNumber = -1;  //出错类型
        int noDefine = -3;      //未定义类型
       // char endChar = '#';
        char nullChar = '\0';

        public WordPicker() {
            wordTypeNumber = keyWordTable.Length;
            numberTypeNumber = keyWordTable.Length + 1;
            charTypeNumber = keyWordTable.Length + 2;
            stringTypeNumber = keyWordTable.Length + 3;

            operatorSort = new string[operatorTable.Length];
            Array.Copy(operatorTable, operatorSort, operatorTable.Length);
            Array.Sort(operatorSort);
            Array.Reverse(operatorSort);
        }

        static void Main(string[] args) {

            WordPicker p = new WordPicker();

            int over = 1;
            string file = "text.txt";
            p.input = File.ReadAllText(file);
            StreamWriter sw =new StreamWriter("result.txt");
            while(over > p.errorTypeNumber ) {
                Word w = p.scanner();
                if(w.typeNum < p.errorTypeNumber) {
                    Console.WriteLine(w);
                    sw.WriteLine(w.ToShow());
                }
                over = w.typeNum;
            }
            sw.Flush();
            sw.Close();
            Console.ReadKey();
        }

        /// <summary>
        /// 读词
        /// </summary>
        /// <returns></returns>
        Word scanner() {
            Word myWord;
            myWord.typeNum = -1;
            myWord.word = "";
            read();
            readValidChar();
            //标识符
            if(char.IsLetter(character)) {
                readWord(ref myWord);
            }//数值
            else if(char.IsDigit(character)) {
                readDigit(ref myWord);
            }//字符常量
            else if(character == '\'') {
                readConstChar(ref myWord);
            }//字符串
            else if(character == '\"') {
                readConstString(ref myWord);
            }/*//结束符
            else if(character == endChar) {
                myWord.word = "" + endChar;
                myWord.typeNum = endTypeNumber;
            }*///空值
            else if(character == nullChar) {
                myWord.word = "null";
                myWord.typeNum = errorTypeNumber;
            }//其他字符
            else {
                readOtherChar(ref myWord);
            }
            return myWord;

        }
        /// <summary>
        /// 标识符
        /// </summary>
        /// <param name="myWord"></param>
        private void readWord(ref Word myWord) {
            while(char.IsLetter(character) || char.IsDigit(character)) {
                myWord.word += character;
                read();
            }
            retract();
            myWord.typeNum = getKeyTypeNumber(myWord.word);

        }
        /// <summary>
        /// 其他字符
        /// </summary>
        /// <param name="myWord"></param>
        private void readOtherChar(ref Word myWord) {
            string s = "" + character;
            for(int i = 0; i < 2; i++) {
                read();
                if(character == nullChar) {
                    break;
                }
                s += character;
            }
            foreach(string op in operatorSort) {
                if(s.StartsWith(op)) {
                    input_index -= s.Length - op.Length;
                    s = op;
                    break;
                }
            }
            myWord.word = s;
            myWord.typeNum = getOperatorTypeNumber(myWord.word);
        }



        /// <summary>
        /// 识别数字常量
        /// </summary>
        /// <param name="myWord"></param>
        private void readDigit(ref Word myWord) {
            while(char.IsDigit(character)) {
                myWord.word += character;
                read();
            }
            if(character == '.') {
                myWord.word += character;
                read();
                while(char.IsDigit(character)) {
                    myWord.word += character;
                    read();
                }
            }
            retract();
            myWord.typeNum = numberTypeNumber;
            // return myWord;
        }

        /// <summary>
        /// 识别字符常量
        /// </summary>
        /// <param name="myWord"></param>
        private void readConstChar(ref Word myWord) {
            // myWord.word = "" + character;
            read();
            //读取直到'\''结束
            while(character != '\'') {
                myWord.word += character;
                read();
                //读到空字符或结束字符
                if(character == nullChar /*|| character == endChar*/|| char.IsControl(character)) {
                   /* if(character == endChar) {
                        myWord.word +=endChar;
                    } */                                   
                    myWord.typeNum = errorTypeNumber;
                    return;
                }
            }
            // myWord.word += character;
            Match r = Regex.Match(myWord.word, "^(\\\\([0-7]{1,3}|x[0-9a-fA-F]+|[abfnrtv\\\\\'\"?])|[^\\\\])$");
            //转义字符模式匹配
            if(!r.Success) {
                myWord.typeNum = errorTypeNumber;
                return;
            }
            myWord.typeNum = charTypeNumber;
        }
        /// <summary>
        /// 识别常量字符串
        /// </summary>
        /// <param name="myWord"></param>
        private void readConstString(ref Word myWord) {
            // myWord.word = "" + character;
            read();
            while(character != '\"') {
                myWord.word += character;
                read();
                //读到空字符或结束字符
                if(character == nullChar|| char.IsControl(character)) {
                  // myWord.word += "0";
                   myWord.typeNum = errorTypeNumber;
                    return;
                }
            }
            // myWord.word += character;

            //转义字符模式匹配
            if(!isLegalString(myWord.word)) {
                myWord.typeNum = errorTypeNumber;
                return;
            }
            myWord.typeNum = stringTypeNumber;
        }

        /// <summary>
        /// 合法字符串书写
        /// </summary>
        /// <param name="word"></param>
        /// <returns></returns>
        private bool isLegalString(string word) {

            int i = 0;
            while(i < word.Length) {
                if(word[i] == '\\') {
                    if(++i == word.Length)
                        return false;
                    foreach(char c in translateChar) {
                        if(c == word[i]) {
                            goto aLabel;
                        }
                    }
                    return false;
                }
            aLabel:
                i++;
            }

            return true;
        }

        const string translateChar = "abfnrtv\\\'\"?";
        const string realChar = "\a\b\f\n\r\t\v\\\'\"?";
        /// <summary>
        /// 转换为真实字符串
        /// </summary>
        /// <param name="word"></param>
        /// <returns></returns>
        private string toRealString(string word) {
            string res = "";
            int index;
            for(int i = 0; i < word.Length; i++) {
                if(word[i] == '\\') {
                    if(++i == word.Length)
                       throw new Exception("字符串以\\结尾异常");

                    index = translateChar.IndexOf(word[i]);
                    if(index == -1)
                        throw new Exception("\\"+ word[i] + "解析异常");
                    res += realChar[index];                   
                }
                else {
                    res += word[i];
                }
            }
            return res;
        }
        /// <summary>
        /// 读一个字符
        /// </summary>
        void read() {
            if(input.Length <= input_index) {
                character = '\0';
            }
            else
                character = input[input_index++];
        }
        /// <summary>
        /// 去除无效字符
        /// </summary>
        void readValidChar() {

            while(char.IsWhiteSpace(character)) {
                if(input.Length <= input_index) {
                    character = '\0';
                    return;
                }
                character = input[input_index++];
            }
            //判断注释
            if(character == '/'&& input.Length > input_index+1) {
                ignoreNote();
            }
        }

        private void ignoreNote() {
           
            //注释‘//’
            if(input[input_index] == '/') {
                input_index++;
                do {
                    if(input.Length <= input_index) {
                        character = '\0';
                        return;
                    }
                    character = input[input_index++];
                } while('\n' != character);
                read();
                readValidChar();
            }//注释‘/*。。。*/’
            else if(input[input_index] == '*') {
                input_index++;
                while(true) {
                    if(input.Length <= input_index) {
                        character = '\0';
                        return;
                    }
                    character = input[input_index++];
                    if('*' == character && input.Length >= input_index + 1 && '/' == input[input_index]) {
                        input_index++;
                        read();
                        readValidChar();
                        return;
                    }

                }
            }
        }
       
        /// <summary>
        /// 获取关键字编码
        /// </summary>
        /// <returns></returns>
        int getKeyTypeNumber(string s) {
            for(int i = 0; i < keyWordTable.Length; i++) {
                if(keyWordTable[i] == s) {
                    return i;
                }
            }

            return keyWordTable.Length;
        }

        int getOperatorTypeNumber(string s) {
            int start = 100;
            for(int i = 0; i < operatorTable.Length; i++) {
                if(operatorTable[i] == s) {
                    return start + i;
                }
            }
            return noDefine;
        }
        void retract() {
            input_index--;
        }

    }
}

输入文件:

int main(){	
 // int x=9; //int a=c;            
 // if (x>0.123)  
 ///* foolish abc  */x=2*x+1/3;// int c=0;
//int b=10;	
 /*while(b!=0){
	b--;
}*/
 /* do{
	  int /*fdfd* / a=2.1;
  }while(!1);*/
  int ab;
  int a>>=ab;
  a=ab+-a;
  return 0;
}
 //
# 

输出: 

猜你喜欢

转载自blog.csdn.net/moakun/article/details/86411814