编译原理相关问题:
编译环境:C++,MFC
/*
问题描述:
1. 把C++源代码中的各类单词(记号)进行拼装分类。
C++语言包含了几种类型的单词(记号):标识符,关键字,数(包括整数、浮点数),字符串、注释、特殊符号(分界符)和运算符号等【详细的单词类别及拼装规则见最底下图片】。
2.要求应用程序应为Windows界面。
3.打开一个C++源文件,列出所有可以拼装的单词(记号)。
测试样例:
运行效果样本
C++源程序:
Test.cpp
#include<iostream.h>
main()
{
int i;
cin>>i;
if (i>3) cout<<“ok”;
}
扫描结果:
# 特殊符号
Include 关键字
<iostream. h> 特殊符号
main 关键字
( 特殊符号
) 特殊符号
{ 特殊符号
int 关键字
i 标识符
; 特殊符号
cin 关键字
>> 特殊符号
i 标识符
; 特殊符号
if 关键字
( 特殊符号
i 标识符
> 特殊符号
3 数
) 特殊符号
cout 关键字
<< 特殊符号
“ok” 串
; 特殊符号
} 特殊符号
*/
测试文件如下:
测试用例.txt:(未通过)
// ConsoleApplication81.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include<iomanip>
#include<algorithm>
#include<map>
#include<set>
using namespace std;
int next1[4][2] = { {1,0},{-1,0},{0,1},{0,-1} };
/*asfsdfsdfsdf*/
int main()
{
int _abc;
int _a123;
int _____a;
int _ABC;
int _A12;
int A;
int b;
int A12;
int b12;
int x = 0b1001;//二进制
int y = 074;//八进制
cout << y;
int z = 0xa3;//16进制
double e = 1.e-3;
double f = 5e2f;
double F = 5e2F;
int B = 0B1001;
int Z = 0XA3;
double h = 1.0e-3;
double g = 1e1;
double o = 1.e3;
double u = 1e3;
double t = .12;
int r = +1;
int ab = -1;
double E = -1.e-3;
cout << t;
int startState = 1;
int state = startState;
bool quit = false;
while (quit == false)
{
for (int k = 0; k < 4; k++)
{
r += 1;
}
char ch = cin.get(); //ch属于[a-z]
switch (state)
{
case 1:
switch (ch)
{
case 'a':
state = 2;
break;
default:
cout << "错误:出现意料外的字符!" << endl;
cout << "匹配提前终止." << endl;
quit = true;
break;
}
break;
}
}
标识符测试.txt:(通过)
a_bc
a_BC
abc
a12
A43b
A224B
aasg21B
_123ACB
_12abc
_abc12
_abc
_123
a_123
A_213
___________a
a_____b213
关键字测试.txt:(通过)
do while include define ifndef alignas alignof and and_eq asm auto
bitand bitor bool break case catch char char8_t char16_t char32_t
class compl concept const const_cast consteval constexpr constinit
continue co_await co_return co_yield decltype default delete do
double dynamic_cast else enum explicit export extern false float
for friend goto if inline int long mutable namespace new noexcept
not not_eq nullptr operator or or_eq private protected public register
reinterpret_cast requires return short signed sizeof static static_assert
static_cast struct switch template this thread_local throw true try typedef
typeid typename union unsigned using
数字测试.txt:(未通过)
//整数
23;
//正整数、正浮点数
+434;
+4123.4213;
+.13123;
+0.12412;
//负整数、负浮点数
-431;
-213.124124;
-.1213;
-0.3114;
//科学计数法表示数
1.e-3;
52e232f;
512e22F;
1.0e-3213;
1e1;
12.e3;
321e31;
132.e-3;
//正科学计数法表示数
+1.e-3;
+52e232f;
+512e22F;
+1.0e-3213;
+1e1;
+12.e3;
+321e31;
+132.e-3;
//负科学计数法表示数
-1.e-3;
-52e232f;
-512e22F;
-1.0e-3213;
-1e1;
-12.e3;
-321e31;
-132.e-3;
//二进制数
0B01010
0b1110111
//八进制数
072
//十六进制数
0x1234567890ABCDEF
0X1234567890ABCDEF
特殊符号测试.txt:(通过)
new & && # reinterpret_cast - ; << typeid *= ( &= ~ ^ . -- * .*
static_cast sizeof ) [ % > throw ? | \\ , ] >>= :: < ->* } dynamic_cast
! / || { -> " ^= $ == :
delete <= ?: = ++ <<= >> -= |= != \' const_cast >= +
目前自己编写的还不具有可视化界面以及未能成功检测注释,各种表示方法的数(正数,负数,科学计数法表示的数)的代码:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
const vector<string> Keywords = {
"include", "auto", "const", "double", "float", "int", "short", "struct", "unsigned", "enum",
"break", "continue", "else", "for", "long", "signed", "switch", "void", "case", "default",
"goto", "register", "sizeof", "typedef", "volatile", "char", "do", "extern", "if", "return",
"static", "union", "while", "asm", "dynamic_cast", "bool", "explicit", "new", "static_cast", "typeid",
"catch", "false", "operator", "template", "typename", "class", "friend", "private", "this", "using",
"const_cast", "inline", "public", "throw", "virtual", "delete", "mutable", "protected", "true", "wchar_t",
"namespace", "reinterpret_cast", "try", "cin", "cout"
};
bool isAlpha(char c) {
return isalpha(c) || c == '_';
}
bool isDigit(char c) {
return isdigit(c);
}
bool isSpace(char c) {
return isspace(c);
}
bool isKeyword(const string& word) {
return find(Keywords.begin(), Keywords.end(), word) != Keywords.end();
}
bool isOperator(char c) {
return c == '+' || c == '-' || c == '*' || c == '/' || c == '=' || c == '&' || c == '|' || c == '!';
}
void processWord(const string& word) {
if (isKeyword(word)) {
cout << word << "\t\t关键字" << endl;
}
else {
cout << word << "\t\t标识符" << endl;
}
}
void processNumber(const string& number) {
cout << number << "\t\t数值" << endl;
}
void processOperator(char c) {
string op;
op += c;
char nextChar = cin.peek();
if ((c == '+' || c == '-' || c == '=') && nextChar == c) {
op += nextChar;
cin.ignore(); // 忽略下一个字符
}
cout << op << "\t\t运算符号" << endl;
}
void processComment() {
char c = cin.get();
char nextChar = cin.peek();
if (nextChar == '/') {
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // 忽略到行尾的所有字符
cout << "//\t\t注释" << endl;
}
else if (nextChar == '*') {
cin.ignore(); // 忽略 '*'
while (true) {
c = cin.get();
nextChar = cin.peek();
if (c == '*' && nextChar == '/') {
cin.ignore(); // 忽略 '/'
break;
}
}
cout << "/*...*/\t\t注释" << endl;
}
}
int main() {
string input;
char c;
cout << "请选择需要分析的源文件:1,程序内置源文件;2,输入文件的路径" << endl;
int choose;
cin >> choose;
if (choose == 2) {
cout << "请输入文件路径: ";
cin >> input;
ifstream file(input);
if (!file.is_open()) {
cout << "无法打开文件!" << endl;
return 1;
}
while (file.get(c)) {
if (isAlpha(c)) {
string word;
word += c;
while (file.get(c) && (isAlpha(c) || isDigit(c))) {
word += c;
}
file.unget(); // 将最后一个字符放回流中
processWord(word);
}
else if (isDigit(c)) {
string number;
number += c;
while (file.get(c) && (isDigit(c) || c == '.')) {
number += c;
}
file.unget(); // 将最后一个字符放回流中
processNumber(number);
}
else if (isSpace(c)) {
continue; // 忽略空格
}
else if (c == '/' && (file.peek() == '/' || file.peek() == '*')) {
file.unget(); // 将 '/' 字符放回流中
processComment();
}
else if (isOperator(c)) {
processOperator(c);
}
}
file.close();
}
else {
cout << "程序内置源文件分析:" << endl;
cin.ignore(); // 忽略前一个输入的换行符
while (cin.get(c)) {
if (isAlpha(c)) {
string word;
word += c;
while (cin.get(c) && (isAlpha(c) || isDigit(c))) {
word += c;
}
cin.unget(); // 将最后一个字符放回流中
processWord(word);
}
else if (isDigit(c)) {
string number;
number += c;
while (cin.get(c) && (isDigit(c) || c == '.')) {
number += c;
}
cin.unget(); // 将最后一个字符放回流中
processNumber(number);
}
else if (isSpace(c)) {
continue; // 忽略空格
}
else if (c == '/' && (cin.peek() == '/' || cin.peek() == '*')) {
cin.unget(); // 将 '/' 字符放回流中
processComment();
}
else if (isOperator(c)) {
processOperator(c);
}
}
}
return 0;
}





