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