导读:本期聚焦于小伙伴创作的《C++如何实现简单的词法分析器?C++字符串处理实现简单公式解析的方法是什么》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C++如何实现简单的词法分析器?C++字符串处理实现简单公式解析的方法是什么》有用,将其分享出去将是对创作者最好的鼓励。

词法分析器是编译器或者解析器的第一个处理模块,它的核心作用是将输入的字符流拆分成一个个有意义的词法单元,也就是我们常说的token。在简单公式解析的场景中,我们需要识别的token通常包括数字、四则运算符、括号以及可能的空白字符。通过C++的字符串处理能力,我们可以逐个遍历输入公式的字符,根据字符的类型完成token的提取和分类。

C++如何实现简单的词法分析器?C++字符串处理实现简单公式解析的方法是什么

词法分析的核心设计思路

实现简单公式解析的词法分析器,首先需要定义清楚要识别的token类型,常见类型如下:

  • 数字类型:包括整数和小数,由连续的数字字符和最多一个小数点组成
  • 运算符类型:包括加、减、乘、除四种基础四则运算符
  • 括号类型:左括号和右括号,用于改变运算优先级
  • 结束符:表示输入公式已经遍历完成

整个分析流程可以分为三个步骤:首先跳过输入中的空白字符,然后判断当前字符的类型,接着提取对应类型的完整token,最后返回token给后续的语法分析模块使用。

Token结构定义

我们首先需要定义一个结构体来存储每个token的信息,包含token的类型和对应的字符串值:

#include <string>
#include <vector>
#include <cctype>

// 定义token类型枚举
enum class TokenType {
    NUMBER,   // 数字
    PLUS,     // 加号 +
    MINUS,    // 减号 -
    MULTIPLY, // 乘号 *
    DIVIDE,   // 除号 /
    LPAREN,   // 左括号 (
    RPAREN,   // 右括号 )
    END       // 结束符
};

// 定义token结构体
struct Token {
    TokenType type;  // token类型
    std::string value; // token对应的字符串值
};

词法分析器类实现

接下来我们实现一个词法分析器类,它接收输入的公式字符串,提供获取下一个token的方法:

class Lexer {
private:
    std::string input;  // 输入的公式字符串
    int pos;            // 当前遍历到的位置索引
    char currentChar;   // 当前指向的字符

    // 前进到下一个字符
    void advance() {
        pos++;
        if (pos < input.size()) {
            currentChar = input[pos];
        } else {
            currentChar = ''; // 到达末尾
        }
    }

    // 跳过空白字符
    void skipWhitespace() {
        while (currentChar != '' && isspace(currentChar)) {
            advance();
        }
    }

    // 提取数字token,支持整数和小数
    Token getNumber() {
        std::string numStr;
        // 收集整数部分
        while (currentChar != '' && isdigit(currentChar)) {
            numStr += currentChar;
            advance();
        }
        // 处理小数点和小数部分
        if (currentChar == '.') {
            numStr += currentChar;
            advance();
            while (currentChar != '' && isdigit(currentChar)) {
                numStr += currentChar;
                advance();
            }
        }
        return {TokenType::NUMBER, numStr};
    }

public:
    // 构造函数,初始化输入和位置
    Lexer(const std::string& inputStr) : input(inputStr), pos(0) {
        if (!input.empty()) {
            currentChar = input[0];
        } else {
            currentChar = '';
        }
    }

    // 获取下一个token
    Token getNextToken() {
        while (currentChar != '') {
            // 处理空白字符
            if (isspace(currentChar)) {
                skipWhitespace();
                continue;
            }

            // 处理数字
            if (isdigit(currentChar)) {
                return getNumber();
            }

            // 处理运算符和括号
            switch (currentChar) {
                case '+':
                    advance();
                    return {TokenType::PLUS, "+"};
                case '-':
                    advance();
                    return {TokenType::MINUS, "-"};
                case '*':
                    advance();
                    return {TokenType::MULTIPLY, "*"};
                case '/':
                    advance();
                    return {TokenType::DIVIDE, "/"};
                case '(':
                    advance();
                    return {TokenType::LPAREN, "("};
                case ')':
                    advance();
                    return {TokenType::RPAREN, ")"};
                default:
                    // 遇到无法识别的字符,抛出异常
                    throw std::runtime_error("无法识别的字符: " + std::string(1, currentChar));
            }
        }
        // 遍历完成,返回结束符
        return {TokenType::END, ""};
    }
};

公式解析测试示例

我们可以编写一个简单的测试程序,验证词法分析器是否能正确拆分公式中的各个元素:

#include <iostream>

// 打印token信息的辅助函数
void printToken(const Token& token) {
    switch (token.type) {
        case TokenType::NUMBER:
            std::cout << "数字: " << token.value << std::endl;
            break;
        case TokenType::PLUS:
            std::cout << "加号" << std::endl;
            break;
        case TokenType::MINUS:
            std::cout << "减号" << std::endl;
            break;
        case TokenType::MULTIPLY:
            std::cout << "乘号" << std::endl;
            break;
        case TokenType::DIVIDE:
            std::cout << "除号" << std::endl;
            break;
        case TokenType::LPAREN:
            std::cout << "左括号" << std::endl;
            break;
        case TokenType::RPAREN:
            std::cout << "右括号" << std::endl;
            break;
        case TokenType::END:
            std::cout << "结束符" << std::endl;
            break;
    }
}

int main() {
    // 测试公式
    std::string formula = "12.5 + 3 * (4 - 2) / 2";
    Lexer lexer(formula);

    // 逐个获取并打印token
    Token token;
    do {
        token = lexer.getNextToken();
        printToken(token);
    } while (token.type != TokenType::END);

    return 0;
}

实现注意事项

在实际使用这个简单的词法分析器时,需要注意几个问题:首先是输入公式的合法性校验,如果公式中存在无法识别的字符,程序会直接抛出异常,实际使用中可以根据需求调整错误处理方式。其次是小数点的处理,当前实现只允许一个小数点,如果出现多个小数点的情况会被识别为非法字符。另外这个实现只支持基础的四则运算和括号,如果需要扩展支持更多运算符或者函数,只需要在token类型枚举中添加对应的类型,然后在getNextToken方法中增加对应的识别逻辑即可。

这个简单的词法分析器已经可以完成基础公式的token拆分工作,后续的语法分析模块可以基于这些token完成表达式的求值或者语法树构建,实现完整的公式解析功能。

C++词法分析器C++字符串处理公式解析词法分析算法修改时间:2026-07-07 08:03:32

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。