?? cpp3.cpp
字號:
#include <iostream>
#include <fstream>//文件流頭文件無.h,以下有說明
#include <string>
#include <string.h>//字符串頭文件
#include<stdio.h>//標準輸入輸出
#include <ctype.h>//包含了isalpha等,是字符分類宏
using namespace std;//在目前的版本中可以支持這樣的,不用.h為后綴了
char* ReserveWords[32] = {// 保留字數組定義
"auto","double","int","struct","break",
"else","long","switch","case","enum","register","typedef",
"char","extern","return","union","const","float","short",
"unsigned","continue","for","signed","void","default","goto",
"sizeof","volatile","do","if","while","static"};//,"main"加上后則識別main為保留字
char arrow[] = " ";
/*char arrow[] = " -----> ";
宏定義便于以后的修改
可以定義此項作為結果輸出的分界..如( -----> 5
格式如:dst << strToken << arrow << "1" << enter;
*/
char enter[] = "\r\n";
// 讀入字符ch
char GetChar(ifstream& src)
{
char cRet;
src.get(cRet);//讀入一個字符.get是ifstream中的一個函數
return cRet;
}
// 讀入空格
char GetBC(ifstream& src)//字符型函數
{
char cRet;
src.get(cRet);//同上
while (cRet == ' ')//空格
src.get(cRet);//繼續讀入
return cRet;//返回字符型值
}
// 連接單詞符號
void Concat(char *str, char c)
{
size_t n = strlen(str);//得到目前串長度
str[n++] = c;//作為連接的組合空間
str[n] = '\0';//結束標志
}
// 判斷是否為保留字
bool Reserve(const char* str)
{
bool bRet = false;
for (int i = 0; i < 32; i++)
{
if (strcmp(ReserveWords[i], str) == 0)//是關鍵字的話
{
bRet = true;//true確認
break;
}
}
return bRet;
}
// 回調字符
char Retract(ifstream& src)
{
src.seekg(-1, ios::cur);/*文件流中的一個函數,兩種類型,兩種參數!
seekg(pos_type _Pos);
seekg(off_type _Off,ios_base::seekdir _Way);
_Off
An offset to move the read pointer relative to way.
_Pos
The absolute position in which to move the read pointer.
_Way
One of the ios_base::seekdir enumerations.
Return Value
The stream (*this).
//用于在文件流移動讀指針
*/
return '\0';
}
// 分析函數
void Analyzer(ifstream& src, ofstream& dst)
{
char ch;
char strToken[1024] = "";//初始置空
ch = GetBC(src);//定義ch字符初始空格
// 判斷標識符的情況
if (isalpha(ch))
{
while (isalpha(ch) || isdigit(ch) || ch == '_')
{
Concat(strToken, ch);//判斷是否為單個字符,進行連接
ch = GetChar(src);
}
ch = Retract(src);//字符回調后重新對字符或字符串進行判斷
if (Reserve(strToken))
dst << strToken << arrow << "1" << enter;//輸出流的一種格式
else
dst << strToken << arrow << "2" << enter;//不為保留字,則為數字,有上面的條件判定
}
// 判斷數字的情況
else if (isdigit(ch))
{
while (isdigit(ch))//下個字符不是數字,退出運行過程
{
Concat(strToken, ch);//進行連接,多位數...
ch = GetChar(src);//從標準輸入設備讀取一個字符,若文件結束或出錯,則返回-1
//而getc是從文件中讀入一個字符,若文件結束或出錯,返回EOF
}
Retract(src);//回調字符
dst << strToken << arrow << "3" << enter;//類型3
} // 判斷轉義字符與串的情況
else if (ch == '\'')//是\'轉義字符
{
Concat(strToken, ch);//將其連接
ch = GetChar(src);
while (ch != '\'')//不是\'字符,繼續連接
{
Concat(strToken, ch);
ch = GetChar(src);
}
if (ch != '\'')//界定長度
cerr << "String is too long - more than 1024 bytes!" << endl;
else
{
Concat(strToken, ch);
dst << strToken << arrow << "String" << enter;//串
}
}
// 判斷所有沒有歧義的單目運算符
else if (ch == '+')
dst << ch << arrow << "4" << enter;////類型4,以下輸出,意義相同
else if (ch == '-')
dst << ch << arrow << "4" << enter;
else if (ch == '*')
dst << ch << arrow << "4" << enter;
else if (ch == '/')
dst << ch << arrow << "4" << enter;
else if (ch == '=')
dst << ch << arrow << "4" << enter;
else if (ch == '[')
dst << ch << arrow << "5" << enter;
else if (ch == ']')
dst << ch << arrow << "5" << enter;
else if (ch == ',')
dst << ch << arrow << "5" << enter;
else if (ch == '^')
dst << ch << arrow << "4" << enter;
else if (ch == ';')
dst << ch << arrow << "5" << enter;
else if (ch == '(')
dst << ch << arrow << "5" << enter;
else if (ch == ')')
dst << ch << arrow << "5" << enter;
else if (ch == '{')
dst << ch << arrow << "5" << enter;
else if (ch == '}')
dst << ch << arrow << "5" << enter;
// 判斷<、<>和<=
else if (ch == '<')
{
ch = GetChar(src);
if (ch == '>')
dst << "<>" << arrow << "4" << enter;
else if (ch == '=')
dst << "<=" << arrow << "4" << enter;
else
{
dst << '<' << arrow << "4" << enter;
Retract(src);//<=,<>也即!=
}
}
// 判斷>和>=
else if (ch == '>')
{
ch = GetChar(src);
if (ch == '=')
dst << ">=" << arrow << "4" << enter;//類型4
else
{
dst << '>' << arrow << "4" << enter;//類型4
Retract(src);//>=
}
}
// 判斷.和..
else if (ch == '.')
{
ch = GetChar(src);
if (ch == '.')
dst << ".." << arrow << "2" << enter;//類型2
else
{
dst << '.' << arrow << "2" << enter;//類型2
Retract(src);//.和..
}
}
// 判斷:和:=
else if (ch == ':')
{
ch = GetChar(src);
if (ch == '=')
dst << ":=" << arrow << "4" << enter;//類型4
else
{
dst << ':' << arrow << "2" << enter;//類型2
Retract(src);//:= 逐級判斷,分析為各個獨立個體,所以需要回調分析,保持字符或字符串完整性
}
}
}
int main(int argc, char* argv[])
{
string strSrc;
if (argc == 1) // 命令行的支持
{
cout << "Please input source file\nlike in.txt... \n\n";
getline(cin, strSrc);
/*
if(cin=="in.txt"){
cout << "the source program below:\n";
while(ch=fopen("in.txt","r")!=NULL)
{
printf("%c",ch);
}
cout<<"\n\n"<<"The result has created to out.txt\n";
}
*/
system("pause");//系統暫停,讓用戶確定
}
else
strSrc = argv[1];
ifstream src(strSrc.c_str()); // 打開文件
if (src.fail())
{
cerr << "\aFailed to open \"" << strSrc << "\"!" << endl;//cerr輸出錯誤機制,有聲音提示
return 1;
}
ofstream dst("out.txt");
// 開始解析,整個文件,知道文件尾
while (!src.eof())//
Analyzer(src, dst);
// 收尾工作
src.close();//關閉輸入文件流
dst.close();//關閉輸出文件流
cout << "The result of Analyzing is written into out.txt." << endl;
return 0;//整形返回
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -