词法分析
(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';}elsecharacter = 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;
}//
#
输出: