gpt4 book ai didi

c++ - 如何使 boost::spirit 解析器和词法分析器能够处理包含文件

转载 作者:行者123 更新时间:2023-11-30 03:27:42 29 4
gpt4 key购买 nike

这是一个什么都不做的词法分析器和解析器——它返回读取的字符串。我希望扩展它以便能够处理类似 C++ 的 include 语句。我可以想象如何做到这一点——但我想知道是否有更简单或已经可用的方法。如果我必须这样做,我会实现我自己的迭代器(传递给词法分析器)。这个迭代器将包含

  • 字符串的索引(可能使用 -1 来指示 end() 迭代器)
  • 指向这个字符串的指针

遇到一些 include 语句时,词法分析器会将文件插入到覆盖 include 语句的当前位置的字符串中。你会怎么做?

这是我什么都不做的词法分析器/解析器:

#include <boost/phoenix.hpp>
#include <boost/bind.hpp>
#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/qi.hpp>
#include <algorithm>
#include <iostream>
#include <string>
#include <utility>
#include <vector>

namespace lex = boost::spirit::lex;
namespace qi = boost::spirit::qi;
namespace phoenix = boost::phoenix;


template<typename Lexer>
class lexer:public lex::lexer<Lexer>
{ public:
typedef lex::token_def<char> char_token_type;
char_token_type m_sChar;
//lex::token_def<lex::omit> m_sInclude;
lexer(void)
: m_sChar(".")//,
//m_sInclude("^#include \"[^\"]*\"")
{ this->self += m_sChar;
}
};

template<typename Iterator>
class grammar : public qi::grammar<Iterator, std::string()>
{ public:
qi::rule<Iterator, std::string()> m_sStart;
template<typename Tokens>
explicit grammar(Tokens const& tokens)
: grammar::base_type(m_sStart)
{ m_sStart %= *tokens.m_sChar >> qi::eoi;
}
};


int main(int, char**)
{
typedef lex::lexertl::token<std::string::const_iterator, boost::mpl::vector<char> > token_type;
typedef lexer<lex::lexertl::actor_lexer<token_type> > expression_lexer_type;
typedef expression_lexer_type::iterator_type expression_lexer_iterator_type;
typedef grammar<expression_lexer_iterator_type> expression_grammar_type;

expression_lexer_type lexer;
expression_grammar_type grammar(lexer);
const std::string s_ac = "this is a test\n\
#include \"test.dat\"\n\
";
std::string s;
auto pBegin = std::begin(s_ac);
lex::tokenize_and_parse(pBegin, std::end(s_ac), lexer, grammar, s);
}

最佳答案

首先,存在基于 Spirit 的预处理器:Boost Wave (另见 How do I implement include directives using boost::spirit::lex?)

其次,“将包含文件的内容插入字符串值”既无用(出于词法分析目的)又非常低效:

  • 这是无用的,因为包含文件将形成一个标记(!?),这意味着您的解析器无法对包含的内容进行操作
  • 它不是通用的,因为嵌套包含不会以这种方式发生
  • 即使目标只是将包含文件逐字/复制/到等效的输出流,通过将内容完全复制到内存中,通过词法分析器将其复制到解析器中,仅流式传输,这样做的效率非常低出来。您可以只使用最少的分配将输入流虹吸到输出流中。

我建议以下任意组合:

  • 不同的关注点:不要将解析与解释混为一谈。因此,如果您要解析 include 指令,您将返回 include 语句的表示,然后可以将其传递给解释它的代码

  • 一个特殊的、更强的关注点分离案例是将包含处理移至预处理阶段。事实上,一个自定义的迭代器类型可以做到这一点,但我会在它之上构建词法分析器,所以词法分析器不必知道包含,而只是对源进行词法分析,而无需(必须)知道确切的来源.

关于c++ - 如何使 boost::spirit 解析器和词法分析器能够处理包含文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47146548/

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