1. 程式人生 > >編譯原理實驗(四)之解析語言翻譯成三地址程式碼

編譯原理實驗(四)之解析語言翻譯成三地址程式碼

選擇部分C語言的語法成分,設計其詞法語法語義分析程式。

設計並實現一個一遍掃描的詞法語法語義分析程式,將部分C語言的語法成分翻譯成三地址程式碼,要求有一定的出錯提示和錯誤恢復功能。

例如簡單賦值語句:

area=3.14*a*a;
s= 2*3.1416*r*(h+r);

翻譯成字尾式: 

area 3.14 a * a * =
s 2 3.1416 *r*h r +*=

翻譯成三地址程式碼: 

t1=3.14*a;
t2=t1*a;
area=t2;
t3=2*3.1416;
t4=t3*r;
t5=h+r;
t6=t4*t5;
s=t6;

源程式:

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

namespace CLanguage {


    class CLanguage {
        WordStream wordStream = new WordStream("text.txt");

        // List<Error> errors = new List<Error>();

        static void Main(string[] args) {
            CLanguage syntax = new CLanguage();
            syntax.SemanticsParser();
            Console.ReadKey();
        }

        /// <summary>
        /// 語義分析
        /// </summary>
        public void SemanticsParser() {
            do {
                functionParser();
            } while(wordStream.ReadNextWord().typeNum != WordPicker.endTypeNumber);

            if(success) {
                // Console.WriteLine("成功");
                foreach(FourFormula f in list) {
                    Console.WriteLine(f);
                }
                Console.WriteLine("---finish---");
            }

        }

        /// <summary>
        /// 函式
        /// </summary>
        private void functionParser() {

            Word word = wordStream.ReadNextWord();
            //返回型別
            if(!KeyWords.isReturnType(word)) {
                addError(word, "返回值錯誤");
            }
            word = wordStream.ReadNextWord();
            //函式名
            if(!isIdentifier(word)) {
                addError(word, "函式名錯誤");
            }
            //(引數){
            word = wordStream.ReadNextWord();
            if(word.typeNum != Symbols.left_bracket.typeNum) {
                addError(word, "(缺失");
                wordStream.retractWord();
            }
            arguments();
            word = wordStream.ReadNextWord();
            if(word.typeNum != Symbols.right_bracket.typeNum) {
                addError(word, ")缺失");
                wordStream.retractWord();
            }
            word = wordStream.ReadNextWord();
            if(word.typeNum != Symbols.left_curly_bracket.typeNum) {
                addError(word, "{缺失");
                wordStream.retractWord();
            }
            //語句串
            statementSequence();
            //}
            word = wordStream.ReadNextWord();
            if(word.typeNum != Symbols.right_curly_bracket.typeNum) {
                addError(word, "}缺失");
                wordStream.retractWord();
            }

        }

        /// <summary>
        /// 引數
        /// </summary>
        private void arguments() {
            Word word = wordStream.ReadNextWord();
            if(!KeyWords.isType(word)) {
                if(isIdentifier(word))
                    addBeforeError(word, "引數型別缺失");
                else {
                    if(wordStream.LastWord().typeNum == Symbols.comma.typeNum)
                        addBeforeError(word, ",多餘");
                    wordStream.retractWord();
                    return;
                }
            }
            word = wordStream.ReadNextWord();
            if(!isIdentifier(word)) {
                addBeforeError(word, "引數識別符號錯誤");
                if(word.typeNum == Symbols.right_bracket.typeNum) {
                    wordStream.retractWord();
                    return;
                }
            }
            //逗號
            word = wordStream.ReadNextWord();
            if(word.typeNum == Symbols.comma.typeNum) {
                arguments();
            }
            else if(word.typeNum == Symbols.right_bracket.typeNum) {
                wordStream.retractWord();
                return;
            }

        }

        /// <summary>
        /// 判斷是否是識別符號
        /// </summary>
        /// <param name="word"></param>
        /// <returns></returns>
        private bool isIdentifier(Word word) {
            return word.typeNum == WordPicker.identifierTypeNumber;
        }


        /// <summary>
        /// 語串
        /// </summary>
        private void statementSequence() {
            Word word = wordStream.ReadNextWord();
            while(word.typeNum != Symbols.right_curly_bracket.typeNum && word.typeNum != WordPicker.endTypeNumber) {
                statement(word);
                word = wordStream.ReadNextWord();
            }
            wordStream.retractWord();
        }

        /// <summary>
        /// 語句
        /// </summary>
        /// <param name="word"></param>
        private void statement(Word word) {
            if(KeyWords.isType(word)) {
                defineStatement();
            }
            else if(isIdentifier(word)) {
                assignStatement();
            }
            else if(KeyWords.isIfCondition(word)) {
                ifCondition();
            }
            /*else if(KeyWords.isForLoop(word)) {
                forLoop();
            }*/
            else if(KeyWords.isWhileLoop(word)) {
                whileLoop();
            }
            else {
                addError(word, "多餘");
            }
        }

        #region IF語句塊
        /// <summary>
        /// if條件語句
        /// </summary>
        private void ifCondition() {
            //(
            Word word = wordStream.ReadNextWord();
            if(word.typeNum != Symbols.left_bracket.typeNum) {
                addError(word, "(缺失");
                wordStream.retractWord();
            }

            List<FourFormula> trueList = new List<FourFormula>();
            List<FourFormula> falseList = new List<FourFormula>();
            condition(trueList, falseList);
            //)
            word = wordStream.ReadNextWord();
            if(word.typeNum != Symbols.right_bracket.typeNum) {
                addError(word, ")缺失");
                wordStream.retractWord();
            }

            backPatch(trueList, getNextCodeLine());//回填true分支地址

            word = wordStream.ReadNextWord();
            if(word.typeNum == Symbols.left_curly_bracket.typeNum) {//語句塊
                statementSequence();
                word = wordStream.ReadNextWord();
                if(word.typeNum != Symbols.right_curly_bracket.typeNum) {
                    addBeforeError(word, "缺少右花括號");
                    wordStream.retractWord();
                }
            }
            else {
                statement(word);
            }
            FourFormula f=addFourFormula();//true分支結束跳轉
            backPatch(falseList, getNextCodeLine());//回填false分支地址
            elseCondition();//else語句
            backPatch(f, getNextCodeLine());
        }

        

        /// <summary>
        /// else語句
        /// </summary>
        private void elseCondition() {
            Word word = wordStream.ReadNextWord();
            if(word.typeNum != KeyWords.ELSE.typeNum) {

                wordStream.retractWord();
                return;
            }
            word = wordStream.ReadNextWord();
            if(word.typeNum == Symbols.left_curly_bracket.typeNum) {
                statementSequence();
                word = wordStream.ReadNextWord();
                if(word.typeNum != Symbols.right_curly_bracket.typeNum) {
                    addBeforeError(word, "缺少右花括號");
                    wordStream.retractWord();
                }
            }
            else {
                statement(word);
            }
        }
        #endregion

        /// <summary>
        /// for迴圈
        /// </summary>
        private void forLoop() {

        }

        /// <summary>
        /// while迴圈
        /// </summary>
        private void whileLoop() {
            //(
            Word word = wordStream.ReadNextWord();
            if(word.typeNum != Symbols.left_bracket.typeNum) {
                addError(word, "(缺失");
                wordStream.retractWord();
            }

            int startCode = getNextCodeLine();

            List<FourFormula> trueList = new List<FourFormula>();
            List<FourFormula> falseList = new List<FourFormula>();
            condition(trueList, falseList);

            //)
            word = wordStream.ReadNextWord();
            if(word.typeNum != Symbols.right_bracket.typeNum) {
                addError(word, ")缺失");
                wordStream.retractWord();
            }

            backPatch(trueList, getNextCodeLine());//回填true分支地址
            
            word = wordStream.ReadNextWord();
            if(word.typeNum == Symbols.left_curly_bracket.typeNum) {//語句塊
                statementSequence();
                word = wordStream.ReadNextWord();
                if(word.typeNum != Symbols.right_curly_bracket.typeNum) {
                    addBeforeError(word, "缺少右花括號");
                    wordStream.retractWord();
                }
            }
            else {
                statement(word);
            }
            Word w = new Word();
            w.word = "" + startCode;
            addFourFormula(w, null, null, null);
            backPatch(falseList, getNextCodeLine());
        }

        /// <summary>
        /// 條件語句
        /// </summary>
        private void condition(List<FourFormula> trueList, List<FourFormula> falseList) {
            boolExpressStatement(trueList, falseList);
            
        }

        /// <summary>
        /// 獲取下一行地址編號
        /// </summary>
        /// <returns></returns>
        private int getNextCodeLine() {
            return list.Count;
        }

        /// <summary>
        /// 回填跳轉位置
        /// </summary>
        /// <param name="size"></param>
        private void backPatch(List<FourFormula> indexs, int row) {
            foreach(FourFormula f in indexs) {
                f.result = new Word();
                f.result.word = "" + row;
                // getNextLine();
            }
            indexs.Clear();
        }

        private void backPatch(FourFormula f, int row) {
            f.result = new Word();
            f.result.word = "" + row;
        }

        /// <summary>
        /// 定義語句
        /// </summary>
        private void defineStatement() {
            Word word = wordStream.ReadNextWord();
            if(!isIdentifier(word)) {
                addBeforeError(word, "變數名缺失");
                wordStream.retractWord();
            }
            word = wordStream.ReadNextWord();
            if(word.typeNum == Symbols.assign.typeNum) {

                addFourFormula(wordStream.LastWord(), expressStatement(), null, null);
                word = wordStream.ReadNextWord();
            }

            if(word.typeNum == Symbols.comma.typeNum) {
                defineStatement();
            }
            else if(word.typeNum != Symbols.semicolon.typeNum) {
                addBeforeError(word, ";缺失");
                wordStream.retractWord();
            }

        }

        /// <summary>
        /// 賦值語句
        /// </summary>
        private void assignStatement() {

            Word result = wordStream.NowWord();
            Word word = wordStream.ReadNextWord();
            if(word.typeNum != Symbols.assign.typeNum) {
                addBeforeError(word, "=缺失");
                wordStream.retractWord();
            }
            Word arg1 = expressStatement();
            addFourFormula(result, arg1, null, null);
            word = wordStream.ReadNextWord();
            if(word.typeNum != Symbols.semicolon.typeNum) {
                addBeforeError(word, ";缺失");
                wordStream.retractWord();
            }

        }

        #region 表示式解析
        /// <summary>
        /// 表示式
        /// </summary>
        private Word expressStatement() {
            Word express, arg1, arg2;       
            arg1 = express = term();          
            Word word = wordStream.ReadNextWord();
            while(word.typeNum == Symbols.add.typeNum
                || word.typeNum == Symbols.sub.typeNum) {
                arg2 = term();
                express = createTempVar();
                express = createTempVar();
                addFourFormula(express, arg1, arg2, word);
                arg1 = express;
                word = wordStream.ReadNextWord();
            }
            wordStream.retractWord();

            return express;
        }
        /// <summary>
        /// 項
        /// </summary>
        /// <returns></returns>
        private Word term() {
            Word term, arg1, arg2;       
            term = factor();
            arg1 = term;
            Word word = wordStream.ReadNextWord();
            while(word.typeNum == Symbols.mul.typeNum
                || word.typeNum == Symbols.except.typeNum
                || word.typeNum == Symbols.remain.typeNum) {
                arg2 = factor();
                term = createTempVar();
                addFourFormula(term, arg1, arg2, word);
                arg1 = term;
                word = wordStream.ReadNextWord();
            }
            wordStream.retractWord();
            return term;
        }

        /// <summary>
        /// 表示式因子
        /// </summary>
        private Word factor() {
            Word factor = null;
            Word word = wordStream.ReadNextWord();
            if(isValue(word)) {
                factor = word;
            }
            else if(word.typeNum == Symbols.left_bracket.typeNum) {
                factor = expressStatement();
                word = wordStream.ReadNextWord();
                if(word.typeNum != Symbols.right_bracket.typeNum) {
                    addBeforeError(word, ")缺失");
                    wordStream.retractWord();
                }
            }
            else {
                addBeforeError(word, "表示式錯誤");
                wordStream.retractWord();
                //throw new Exception(); 
            }

            return factor;
        }
        #endregion

        #region 布林表示式
        /// <summary>
        /// 表示式
        /// </summary>
        private void boolExpressStatement(List<FourFormula> trueList, List<FourFormula> falseList) {
            boolTerm(trueList, falseList);
            Word word = wordStream.ReadNextWord();
            while(word.typeNum == Symbols.logic_or.typeNum) {
                backPatch(falseList, getNextCodeLine());
                boolTerm(trueList, falseList);                               
                word = wordStream.ReadNextWord();
            }
            wordStream.retractWord();

        }
        /// <summary>
        /// 項
        /// </summary>
        /// <returns></returns>
        private void boolTerm(List<FourFormula> trueList, List<FourFormula> falseList) {
                
            boolFactor(trueList, falseList);
           
            Word word = wordStream.ReadNextWord();
            while(word.typeNum == Symbols.logic_and.typeNum) {
                backPatch(trueList, getNextCodeLine());
                boolFactor(trueList, falseList);
                word = wordStream.ReadNextWord();
            }
            wordStream.retractWord();
           
        }

        /// <summary>
        /// 表示式因子
        /// </summary>
        private void boolFactor(List<FourFormula> trueList, List<FourFormula> falseList) {

            Word word = wordStream.ReadNextWord();
            if(isValue(word)) {
                wordStream.retractWord();
                boolRelation(trueList,falseList);             
            }
            else if(word.typeNum == Symbols.left_bracket.typeNum) {
                if(isExpress()) {
                    wordStream.retractWord();
                    boolRelation(trueList, falseList);
                }
                else {
                    boolExpressStatement(trueList, falseList);
                    word = wordStream.ReadNextWord();
                    if(word.typeNum != Symbols.right_bracket.typeNum) {
                        addBeforeError(word, ")缺失");
                        wordStream.retractWord();
                    }
                }
                
            }
            else if(word.typeNum == Symbols.logic_not.typeNum) {
                boolExpressStatement(falseList,trueList);
            }
            else{
                addBeforeError(word, "布林表示式錯誤");
                wordStream.retractWord();
                //throw new Exception(); 
            }

           
        }

        private bool isExpress() {
            int left = 1;
            int right = 0;
            int words = 1;
            Word word = wordStream.ReadNextWord();
            while(Symbols.isExpressSymbol(word)) {
                if(word.typeNum == Symbols.left_bracket.typeNum) {
                    left++;
                }
                else if(word.typeNum == Symbols.right_bracket.typeNum) {
                    right++;
                }
                word = wordStream.ReadNextWord();
                words++;
            }
            wordStream.retractWord(words);
            return left==right;
        }

        /// <summary>
        /// 關係表示式或布林值
        /// </summary>
        /// <param name="trueList"></param>
        /// <param name="falseList"></param>
        private void boolRelation(List<FourFormula> trueList, List<FourFormula> falseList) {
            Word word = expressStatement();
            Word word2 = null;
            Word op = wordStream.ReadNextWord();
            if(Symbols.isCompareOperator(op)) {
                word2 = expressStatement();
                if(word2 == null) {
                    return ;
                }
            }
            else{
                wordStream.retractWord();
                 op = new Word();
            }            
            
            FourFormula f = addFourFormula(null, word, word2, op);
            trueList.Add(f);
            f = addFourFormula();
            falseList.Add(f);
            
        }


        #endregion

        /// <summary>
        /// 判斷是否是數值變數型別
        /// </summary>
        /// <param name="word"></param>
        /// <returns></returns>
        private bool isValue(Word word) {
            return word.typeNum == WordPicker.numberTypeNumber
                || word.typeNum == WordPicker.identifierTypeNumber
                || word.typeNum == WordPicker.charTypeNumber
                || word.typeNum == WordPicker.stringTypeNumber;
        }

        #region 新增四元式
        List<FourFormula> list = new List<FourFormula>();
        /// <summary>
        /// 儲存四元式
        /// </summary>
        private FourFormula addFourFormula(Word result, Word arg1, Word arg2, Word op) {
            FourFormula fourFormula = new FourFormula();
            fourFormula.result = result;
            fourFormula.arg1 = arg1;
            fourFormula.arg2 = arg2;
            fourFormula.operate = op;
            fourFormula.codeRow = list.Count;
            list.Add(fourFormula);
            return fourFormula;
        }
        private FourFormula addFourFormula() {
            FourFormula fourFormula = new FourFormula();
            fourFormula.codeRow = list.Count;
            list.Add(fourFormula);
            return fourFormula;
        }
        #endregion

        int idNameCount = 0;
        /// <summary>
        /// 建立臨時變數
        /// </summary>
        /// <returns></returns>
        public Word createTempVar() {
            Word word = new Word();
            word.word = "$T" + idNameCount++;
            word.typeNum =WordPicker.tempValTypeNumber;
            return word;
        }
         

        #region 輸出錯誤
        bool success = true;//語法解析結果
        /// <summary>
        /// 輸出在特定之前的錯誤
        /// </summary>
        /// <param name="word"></param>
        /// <param name="v"></param>
        private void addBeforeError(Word word, string v) {
            success = false;
            Console.WriteLine("error:" + word.ToPositionInfo() + "\t在該字之前" + v);
        }
        /// <summary>
        /// 輸出錯誤
        /// </summary>
        /// <param name="word"></param>
        /// <param name="v"></param>
        private void addError(Word word, string v) {
            success = false;
            Console.WriteLine("error:" + word.ToPositionInfo() + "\t" + v);
        }
        #endregion

    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CLanguage {
    /// <summary>
    /// 四元式
    /// </summary>
    class FourFormula {

        public int codeRow;
        public Word result;
        public Word arg1;
        public Word operate;
        public Word arg2;

        public override string ToString() {
            string s = "(" + codeRow + ") ";
            //賦值
            if(result.typeNum>0) {
                s = s + result.word + " = " + arg1.word;
                if(operate != null) {
                    s +=" "+ operate.word;
                }
                if(arg2 != null) {
                    s += " " + arg2.word;
                }
            }
            else if(operate == null) {//直接跳轉
                s += "goto (" + result.word + ")";
            }
            else {//條件跳轉
                s = s + "if " + arg1.word;
               if(operate.word!=null) {
                 s += " " + operate.word + " " + arg2.word;
               }
                s += "  goto (" + result.word + ")";
            }


            return s;
        }
    }

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

namespace CLanguage {
    /// <summary>
    /// 詞
    /// </summary>
    class Word {
        public int typeNum=0;
        public string word;
        public int col=0;
        public int row=0;
        public override string ToString() {
            return "(" + typeNum + "," + word + ")";
        }
        public string ToPositionInfo() {
            return "行:"+(row+1)+"\t列:"+col+"\t碼:"+typeNum + "\t字:" + word;
        }
    }
    

    class WordPicker {
   
        string[] input;
        //int input_index = 0;
        int row = 0;
        int col = 0;
        char character;
       
        /// <summary>
        /// 操作符表
        /// </summary>    
        string[] operatorSort = null;

        public static int identifierTypeNumber;    //變數名型別
        public static int numberTypeNumber;        //數值型別
        public static int charTypeNumber;          //字元型別
        public static int stringTypeNumber;        //字串型別
        public static int endTypeNumber = -1;      //結束符型別
        public static int errorTypeNumber = -2;    //出錯型別
        public static int noDefine = -3;           //未定義型別
        public static char nullChar = '\0';
        public static int tempValTypeNumber;      //臨時變數型別
        public WordPicker(string file) {
            input= File.ReadAllLines(file);           
            identifierTypeNumber = KeyWords.keyWordTable.Length+1;
            numberTypeNumber = KeyWords.keyWordTable.Length + 2;
            charTypeNumber = KeyWords.keyWordTable.Length + 3;
            stringTypeNumber = KeyWords.keyWordTable.Length + 4;
            tempValTypeNumber= KeyWords.keyWordTable.Length + 5;

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



        /// <summary>
        /// 讀詞
        /// </summary>
        /// <returns></returns>
        public Word Scanner() {
            Word myWord;          
            read();
            readValidChar();
            //識別符號
            if(char.IsLetter(character)) {
                myWord=readWord();
            }//數值
            else if(char.IsDigit(character)) {
                myWord = readDigit();
            }//字元常量
            else if(character == '\'') {
                myWord = readConstChar();
            }//字串
            else if(character == '\"') {
                myWord = readConstString();
            }/*//結束符
            else if(character == endChar) {
                myWord.word = "" + endChar;
                myWord.typeNum = endTypeNumber;
            }*///空值
            else if(character == nullChar) {
                myWord = new Word();
                myWord.row = row;
                myWord.col = col;
                myWord.word = "Ending";
                myWord.typeNum = endTypeNumber;
            }//其他字元
            else {
                myWord = readOtherChar();
            }
            return myWord;

        }

        /// <summary>
        /// 識別符號
        /// </summary>
        /// <param name="myWord"></param>
        private Word readWord() {
            Word myWord = new Word();
            myWord.row = row;
            myWord.col = col;
            while(char.IsLetter(character) || char.IsDigit(character)) {
                myWord.word += character;
                read();
            }
            retract();
            myWord.typeNum = KeyWords.getTypeNumber(myWord.word);
            return myWord;
        }

        /// <summary>
        /// 其他字元
        /// </summary>
        /// <param name="myWord"></param>
        private Word readOtherChar() {
            Word myWord = new Word();
            myWord.row = row;
            myWord.col = col;
            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)) {
                    retract(s.Length - op.Length);
                    s = op;
                    break;
                }
            }
            myWord.word = s;
            myWord.typeNum = Symbols.getTypeNumber(myWord.word);
            return myWord;
        }

        /// <summary>
        /// 識別數字常量
        /// </summary>
        /// <param name="myWord"></param>
        private Word readDigit() {
            Word myWord = new Word();
            myWord.row = row;
            myWord.col = col;
            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 Word readConstChar() {
            Word myWord = new Word();
            myWord.row = row;
            myWord.col = col;
            // 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;
                }
            }
            // 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;
            }
            myWord.typeNum = charTypeNumber;
            return myWord;

        }
        /// <summary>
        /// 識別常量字串
        /// </summary>
        /// <param name="myWord"></param>
        private Word readConstString() {
            Word myWord = new Word();
            myWord.row = row;
            myWord.col = col;
            // myWord.word = "" + character;
            read();
            while(character != '\"') {
                myWord.word += character;
                read();
                //讀到空字元或結束字元
                if(character == nullChar || char.IsControl(character)) {
                    // myWord.word += "0";
                    myWord.typeNum = errorTypeNumber;
                    return myWord;
                }
            }
            // myWord.word += character;

            //轉義字元模式匹配
            if(!isLegalString(myWord.word)) {
                myWord.typeNum = errorTypeNumber;
                return myWord;
            }
            myWord.typeNum = stringTypeNumber;
            return myWord;
        }

        /// <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 <= row|| input.Length == row+1 && input[input.Length-1].Length<=col) {
                character = '\0';
            }
            else {
                if(col >= input[row].Length) {
                    col = 0;
                    row++;
                }
                character = input[row][col];
                col++;
            }
                
        }

        /// <summary>
        /// 去除無效字元
        /// </summary>
        void readValidChar() {

            while(char.IsWhiteSpace(character)) {
                if(character == '\0') {
                    return;
                }
                read();              
            }
            //判斷註釋
            if(character == '/' && input[row].Length > col) {
                ignoreNote();
            }
        }

        /// <summary>
        /// 忽視註解
        /// </summary>
        private void ignoreNote() {
            read();
            //註釋‘//’
            if(character == '/') {
                row++;
                col = 0;                              
                read();
                readValidChar();
            }//註釋‘/*。。。*/’
            else if(character == '*') {
               
                read();
                if(character == '\0') {
                    return;
                }
                char c;
                while(true) {
                    
                    c = character;
                    read();
                    if('*' == c && '/' == character) {
                        read();
                        readValidChar();
                        return;
                    }
                    if(character == '\0') {
                        return;
                    }                
                }
            }
            else {
                retract();
            }
        }
 
        /// <summary>
        /// 回退一個字元
        /// </summary>
        void retract() {            
            col=col-2;
            checkCol();
            read();
        }

        /// <summary>
        /// 回退v個字元
        /// </summary>
        /// <param name="v"></param>
        private void retract(int v) {
            if(v == 0)
                return;
            col = col - v - 1;
            checkCol();
            read();
        }

        /// <summary>
        /// 檢查col是否合法
        /// </summary>
        void checkCol() {
            if(col < 0) {
                row--;
                col = input[row].Length + col;
                checkCol();
            }
        }

    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace CLanguage {
    class KeyWords {
        /// <summary>
        /// 關鍵字表
        /// </summary>
        public static 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"};

        public static Word 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;

        static KeyWords() {
            Type t = typeof(KeyWords);

            FieldInfo[] fields = t.GetFields();
            Word word;
            foreach(FieldInfo f in fields)
                if(f.FieldType.Equals(typeof(Word))) {
                    word = new Word();
                    word.word = f.Name.ToLower();
                    word.typeNum = getTypeNumber(word.word);
                    f.SetValue(t, word);
                }
        }
        /// <summary>
        /// 獲取關鍵字編碼
        /// </summary>
        /// <returns></returns>
        public static int getTypeNumber(string s) {
            for(int i = 0; i < keyWordTable.Length; i++) {
                if(keyWordTable[i] == s) {
                    return i+1;
                }
            }

            return WordPicker.identifierTypeNumber;
        }

        public static bool isPrefType(Word w) {
            return SIGNED.typeNum == w.typeNum
               || UNSIGNED.typeNum == w.typeNum;
        }
        public static bool isType(Word w) {
            return INT.typeNum == w.typeNum
                || CHAR.typeNum == w.typeNum
                || DOUBLE.typeNum == w.typeNum
                || FLOAT.typeNum == w.typeNum
                || SHORT.typeNum == w.typeNum;               
        }

        public static bool isReturnType(Word w) {
            return isType(w) || VOID.typeNum == w.typeNum;
        }

        internal static bool isIfCondition(Word word) {
            return word.typeNum == IF.typeNum;
        }

        internal static bool isForLoop(Word word) {
            return word.typeNum == FOR.typeNum;
        }

        internal static bool isWhileLoop(Word word) {
            return word.typeNum == WHILE.typeNum;
        }

        internal static bool isDoLoop(Word word) {
            return  word.typeNum == DO.typeNum;
        }

        internal static bool isKeyWord(Word word) {
            return word.typeNum > 0 && word.typeNum <= keyWordTable.Length;
        }

       
    }
    class Symbols {
        public static string[] operatorTable = {
            "{","}","[","]","(",")","->",".",
            "++","--",
            "!","&&","||",
            "~","&","|","^",
            "+","-","*","/","%",
            "<<",">>",
            "<",">",">=","<=",
            "==","!=","?",":",",",";",
            "=","+=","-=","*=","/=","%=",
            "&=","^=","|=","<<=",">>="
        };

        public static Word left_curly_bracket, right_curly_bracket,
            left_square_bracket, right_square_bracket,
            left_bracket, right_bracket,
            arrow, point, two_add, two_sub,
            logic_not, logic_and, logic_or,
            bitwise_not, bitwise_and, bitwise_or, bitwise_xor,
            add, sub, mul, except, remain,
            left_move, right_move,
            less, greater, greater_equal, less_equal,
            equal, not_equal, question_mark, colon, comma, semicolon,
            assign, add_assign, sub_assign, mul_assign, except_assign, remain_assign,
            and_assign, xor_assign, or_assign, left_move_assign, right_move_assign;

        internal static bool isSemicolo(Word word) {
            return word .typeNum == semicolon.typeNum;
        }

        static Symbols() {
            Type t = typeof(Symbols);

            FieldInfo[] fields = t.GetFields();
            Word word;
            int index = 0;
            foreach(FieldInfo f in fields)
                if(f.FieldType.Equals(typeof(Word))) {
                    word = new Word();
                    word.word = operatorTable[index++];
                    word.typeNum = getTypeNumber(word.word);
                    f.SetValue(t, word);
                }
        }

        public static int getTypeNumber(string s) {
            int start = 100;
            for(int i = 0; i < operatorTable.Length; i++) {
                if(operatorTable[i] == s) {
                    return start + i;
                }
            }
            return WordPicker.noDefine;
        }
        internal static bool isArithmeticOperator(Word w) {
            return w.typeNum == mul.typeNum || w.typeNum == except.typeNum
                || w.typeNum == remain.typeNum
                || w.typeNum == add.typeNum || w.typeNum == sub.typeNum;
        }

        internal static bool isCompareOperator(Word w) {
            return w.typeNum == less.typeNum || w.typeNum == greater.typeNum ||
                w.typeNum == less_equal.typeNum || w.typeNum == greater_equal.typeNum ||
                w.typeNum == equal.typeNum || w.typeNum == not_equal.typeNum;
        }

        internal static bool isExpressSymbol(Word w) {
            return w.typeNum == add.typeNum || w.typeNum == sub.typeNum
                || w.typeNum == mul.typeNum || w.typeNum == except.typeNum|| w.typeNum == remain.typeNum 
                || w.typeNum == left_bracket.typeNum || w.typeNum == right_bracket.typeNum
                || w.typeNum == WordPicker.identifierTypeNumber|| w.typeNum == WordPicker.numberTypeNumber;
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CLanguage {
    /// <summary>
    /// 讀詞快取流
    /// </summary>
    class WordStream {
        WordPicker wordPicker;
        List<Word> words = new List<Word>();
        int index = -1;

        public WordStream(string file) {
            wordPicker = new WordPicker(file);
        }

        /// <summary>
        /// 讀取下一個詞
        /// </summary>
        /// <returns></returns>
        public Word ReadNextWord() {
            index++;
            if(words.Count <= index) {
                Word w = wordPicker.Scanner();
                if(words.Count == 0 || words[words.Count - 1].typeNum != WordPicker.endTypeNumber)
                    words.Add(w);
                index = words.Count - 1;
            }
            return words[index];
        }
        /// <summary>
        /// 現在的詞
        /// </summary>
        /// <returns></returns>
        public Word NowWord() {

            if(words.Count > index && index >= 0) {
                return words[index];
            }
            return null;
        }
        /// <summary>
        /// 上一個詞
        /// </summary>
        /// <returns></returns>
        public Word LastWord() {

            if(index > 0) {

                return words[index - 1];
            }
            else {
                return null;
            }

        }
        /// <summary>
        /// 回退一個詞
        /// </summary>
        public void retractWord() {

            if(index >= 0) {
                index--;
            }

        }
        public void retractWord(int n) {

            if(index >= 0) {
                index-=n;
            }

        }
    }
}

輸入:

void main(){
	int first=30;	
	int second=first*20-5;
	int three=second*3-20;
	if(first-second>three){
		three=23;
	}
}

輸出: