编译原理第一次实验

实验要求:

1、根据以下的正规式,编制正规文法,画出状态图;
标识符
<字母>(<字母>|<数字字符>)*
十进制整数
0 | (1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9*)
八进制整数
01|2|3|4|5|6|7)(0|1|2|3|4|5|6|7*
十六进制整数
0x0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f*
运算符和界符
+ - * / > < = ( )
关键字
if then else while do main
2、根据状态图,设计词法分析函数 int scan( ),完成以下功能:
1) 从文本文件中读入测试源代码,根据状态转换图,分析出一个单词,
2) 以二元式形式输出单词(单词种类,值)
关键字:ifintforwhiledoreturnbreakcontinue;单词种别码为 1
标识符;单词种别码为 2
常数为无符号整形数;单词种别码为 3
运算符包括:+-*/=、 、<=<=!= ;单词种别码为 4
分隔符包括:,;{}();单词种别码为 53、编写测试程序,反复调
用函数 scan( ),输出单词种别和属性。
代码实现:
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>

using namespace std;

// 定义单词种别码
#define KEYWORD 1
#define IDENTIFIER 2
#define CONSTANT 3
#define OPERATOR 4
#define DELIMITER 5

// 关键字列表
string keywords[] = {"if", "int", "for", "while", "do", "return", "break", "continue"};

// 判断是否为关键字
bool isKeyword(const string& str) {
    for (int i = 0; i < sizeof(keywords) / sizeof(keywords[0]); i++) {
        if (keywords[i] == str) return true;
    }
    return false;
}

// 词法分析函数
int scan(ifstream& file) {
    char ch;
    string token;
    while (file.get(ch)) {
        if (isspace(ch)) continue; // 跳过空白字符

        // 识别标识符或关键字
        if (isalpha(ch) || ch == '_') {
            token += ch;
            while (file.get(ch) && (isalnum(ch) || ch == '_')) {
                token += ch;
            }
            file.unget(); // 回退一个字符
            if (isKeyword(token)) {
                cout << "(" << KEYWORD << ", " << token << ")" << endl;
            } else {
                cout << "(" << IDENTIFIER << ", " << token << ")" << endl;
            }
            token.clear();
        }
        // 识别数字常量
        else if (isdigit(ch)) {
            token += ch;
            while (file.get(ch) && isdigit(ch)) {
                token += ch;
            }
            file.unget();
            cout << "(" << CONSTANT << ", " << token << ")" << endl;
            token.clear();
        }
        // 识别运算符
        else if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '=' || ch == '<' || ch == '!') {
            token += ch;
            // 处理双字符运算符 <=、!=
            if (ch == '<' || ch == '!') {
                char nextCh = file.get();
                if (nextCh == '=') {
                    token += nextCh;
                } else {
                    file.unget();
                }
            }
            cout << "(" << OPERATOR << ", " << token << ")" << endl;
            token.clear();
        }
        // 识别分隔符
        else if (ch == ',' || ch == ';' || ch == '{' || ch == '}' || ch == '(' || ch == ')') {
            cout << "(" << DELIMITER << ", " << ch << ")" << endl;
        }
        // 其他情况报错
        else {
            cout << "Error: Invalid character '" << ch << "'" << endl;
        }
    }
    return 0;	
}

int main() {
    ifstream file("source_code.txt");
    if (!file.is_open()) {
        cerr << "Error: Unable to open file!" << endl;
        return 1;
    }

    scan(file);
    file.close();
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值