标记算术表达式
Tokenizing an arithmetic expression?
本文关键字:表达式 更新时间:2023-10-16
假设我有:
3.14 + 3 * (7.7/9.8^32.9 )
我需要标记这个输入字符串:
3.14
+
3
*
(
7.7
/
9.8
^
32.9
)
有没有一种方便的方法可以使用 STL 中的字符串流或其他东西来做到这一点,或者我应该一次查看输入 1 个字符并自己做吗?
这取决于你所说的"方便"是什么意思。您可以使用stringstream
轻松完成此操作,但我不知道这是否是您正在寻找的:
#include <iostream>
#include <vector>
#include <sstream>
using namespace std;
struct token{
char c;
float f;
bool number;
token():number(false),c(0){};
};
vector<token> split(string input)
{
stringstream parser(input);
vector<token> output;
while(parser)
{
token t;
if(isalnum(parser.peek()))
parser >> t.f;
else
parser >> t.c;
t.number = (t.c==0);
output.push_back(t);
}
output.pop_back();
return output;
}
int main()
{
string input = "3.14 + 3 * (7.7/9.8^32.9 )";
vector<token> tokens = split(input);
for(unsigned int i=0;i<tokens.size();i++)
{
if(tokens[i].number) cout << "number: " << tokens[i].f << endl;
else cout << "sign: " << tokens[i].c << endl;
}
}
通常你会使用 Flex/Bison
来生成一个简单的词法分析器和可选的解析器。或者,如果您追求仅编译器解决方案C++
- Boost.Spirit
(示例)。我相信,不存在你想要的纯粹STL
解决方案。
我赞成 Flex/Bison 方法,所以你用 Flex 编写的分词器将是:
%{
#include <iostream>
#include <memory>
%}
%option prefix="Calc"
%option noyywrap
%option c++
ws [ t]+
dig [0-9]
num1 [-+]?{dig}+.?([eE][-+]?{dig}+)?
num2 [-+]?{dig}*.{dig}+([eE][-+]?{dig}+)?
number {num1}|{num2}
%%
{ws} /* skip */
{number} std::cout << "=> number " << YYText() << 'n';
"+"|"-"|"*"|"/"|"^" std::cout << "=> operator " << YYText() << 'n';
"("|")" std::cout << "=> parenthesis " << YYText() << 'n';
. std::cout << "=> unknown " << YYText() << 'n';
%%
int main( int argc, char **argv )
{
std::unique_ptr<FlexLexer> lexer(new CalcFlexLexer);
while(lexer->yylex());
return 0;
}
和编译命令行:
$ flex calc.l
$ g++-4.7 -std=c++11 -o calc lex.Calc.cc
$ calc
1 + (2e4^3)
=> number 1
=> operator +
=> parenthesis (
=> number 2e4
=> operator ^
=> number 3
=> parenthesis )
相关文章:
- (C++)分析树以计算返回错误值的简单算术表达式
- 在VS2010-VS2015下编译时,如何使用decltype作为较大类型表达式的LHS
- 提升精神:解析布尔表达式并简化为规范范式
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 使用正则表达式regex_search在字符串中查找字符串
- 如何确认我的constexpr表达式实际上已经在编译时执行
- 概念中的cv限定符需要表达式参数列表
- 为什么constexpr的性能比正常表达式差
- 对于结构,表达式必须是可修改的ivalue
- 当一个值是非常量但用常量表达式初始化时使用constexpr
- 将fold表达式与std::一起用于两个元组
- 断言中的Fold表达式在某些计算机上编译,但在其他计算机上不编译
- 标记 '","' 之前的预期主表达式
- gcc和clang在表达式是否为常量求值的问题上存在分歧
- 如何计算具有指定类型的表达式的相对精度和绝对精度
- 带有用户定义类的c++折叠表达式
- 即使使用调试编译标志,表达式也是"optimized out"
- holeMenuProgram.cpp:38:1 错误:'}'令牌之前的预期主表达式
- 在 C++ 中使用正则表达式错误时出现问题 括号表达式中的范围无效
- 这 4 个 lambda 表达式之间有什么区别?