gpt4 book ai didi

c++ - 根据特定条件从文件中检索每个标记

转载 作者:行者123 更新时间:2023-11-28 04:35:49 26 4
gpt4 key购买 nike

我正在尝试为函数式语言创建词法分析器,其中一种方法应该允许在每次调用时返回文件的下一个标记。例如:

func main() {
var MyVar : integer = 3+2;
}

所以我希望每次调用 next 方法时,返回该序列中的下一个标记;在那种情况下,它看起来像这样:

func
main
(
)
{
var
MyVar
:
integer
=
3
+
2
;
}

除了我得到的结果不是我所期望的:

func
main(
)

{





var
MyVar
:

integer
=

3+
2

}

这是我的方法:

token_t Lexer::next() {
token_t ret;
std::string token_tmp;
bool IsSimpleQuote = false; // check string --> "..."
bool IsDoubleQuote = false; // check char --> '...'
bool IsComment = false; // check comments --> `...`
bool IterWhile = true;
while (IterWhile) {
bool IsInStc = (IsDoubleQuote || IsSimpleQuote || IsComment);
std::ifstream file_tmp(this->CurrentFilename);
if (this->eof) break;
char chr = this->File.get();
char next = file_tmp.seekg(this->CurrentCharIndex + 1).get();
++this->CurrentCharInCurrentLineIndex;
++this->CurrentCharIndex;
{
if (!IsInStc && !IsComment && chr == '`') IsComment = true; else if (!IsInStc && IsComment && chr == '`') { IsComment = false; continue; }
if (IsComment) continue;
if (!IsInStc && chr == '"') IsDoubleQuote = true;
else if (!IsInStc && chr == '\'') IsSimpleQuote = true;
else if (IsDoubleQuote && chr == '"') IsDoubleQuote = false;
else if (IsSimpleQuote && chr == '\'') IsSimpleQuote = false;
}
if (chr == '\n') {
++this->CurrentLineIndex;
this->CurrentCharInCurrentLineIndex = -1;
}
token_tmp += chr;
if (!IsInStc && IsLangDelim(chr)) IterWhile = false;
}
if (token_tmp.size() > 1 && System::Text::EndsWith(token_tmp, ";") || System::Text::EndsWith(token_tmp, " ")) token_tmp.pop_back();
++this->NbrOfTokens;
location_t pos;
pos.char_pos = this->CurrentCharInCurrentLineIndex;
pos.filename = this->CurrentFilename;
pos.line = this->CurrentLineIndex;
SetToken_t(&ret, token_tmp, TokenList::ToToken(token_tmp), pos);
return ret;
}

这是 IsLangDelim 函数:

bool IsLangDelim(char chr) {
return (chr == ' ' || chr == '\t' || TokenList::IsSymbol(CharToString(chr)));
}

TokenList 是一个命名空间,其中包含 token 列表以及一些函数(如本例中的 IsSymbol)。

我已经尝试过此方法的其他版本,但结果几乎总是一样。

你知道如何改进这个方法吗?

最佳答案

您的问题的解决方案是使用 std::regex。开始时理解语法有点困难,但是理解之后,您将始终使用它。

并且,它旨在查找 token 。

具体的条件可以用正则字符串表示。

对于您的情况,我将使用:std::regex re(R"#((\w+|\d+|[;:\(\)\{\}\+\-\*\/\%\=]))#");

这意味着:

  • 寻找一个或多个字符(即一个词)
  • 寻找一位或多位数字(即整数)
  • 或者寻找各种有意义的运算符(如“+”、“-”、“{”等)

您可以为您正在搜索的所有其他内容扩展正则表达式。您还可以对正则表达式结果进行正则表达式。

请看下面的例子。这将从您提供的输入创建您显示的输出。

并且,您描述的任务只是 main 中的一个语句。

#include <iostream>
#include <string>
#include <algorithm>
#include <regex>

// Our test data (raw string) .
std::string testData(
R"#(func main() {
var MyVar : integer = 3+2;
}
)#");

std::regex re(R"#((\w+|\d+|[;:\(\)\{\}\+\-\*\/\%\=]))#");

int main(void)
{
std::copy(
std::sregex_token_iterator(testData.begin(), testData.end(), re, 1),
std::sregex_token_iterator(),
std::ostream_iterator<std::string>(std::cout, "\n")
);

return 0;
}

关于c++ - 根据特定条件从文件中检索每个标记,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51469251/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com