C++ 如何为用户提供给定boost::spirit语法的高级自动完成建议?

C++ 如何为用户提供给定boost::spirit语法的高级自动完成建议?,c++,parsing,autocomplete,boost-spirit,C++,Parsing,Autocomplete,Boost Spirit,这实际上是在我前面的问题之后建立起来的: 在Sehe解决方案中,我添加了语法着色注释器: 首先采用提示结构(注意:ast\u type\t是一个enum类): 这通常是有效的,但我撞到了另一个拦路车;我需要自动完成,它实际上可以根据以前解析的值构建建议的动态列表;最好的例子是使用sehe对原始问题的评论中的foo.member1.member2。我不允许成员定义在解析文本本身中,它们总是由外部C++类提供;p> 一个C++类的例子: class member_provider_t {

这实际上是在我前面的问题之后建立起来的:

在Sehe解决方案中,我添加了语法着色注释器:

首先采用
提示
结构(注意:
ast\u type\t
是一个
enum类
):

这通常是有效的,但我撞到了另一个拦路车;我需要自动完成,它实际上可以根据以前解析的值构建建议的动态列表;最好的例子是使用sehe对原始问题的评论中的
foo.member1.member2
。我不允许成员定义在解析文本本身中,它们总是由外部C++类提供;p>

一个C++类的例子:

class member_provider_t
{
     public: virtual ~member_provider_t() {}
     public: virtual std::vector<std::string> possible_identifiers_after(...) = 0;
}
(*
关于
-这取决于到目前为止解析的整个url)


如果这是不可能的,那么任何其他方法都可以将尽可能多的解析部分传递给provider函数。

关于语法高亮显示,您见过这些吗

关于问题的第二部分,即上下文相关完成,您只需要进行语义分析。这里要记住的最重要的事情是分离解析和语义分析,以简化您的生活

在中,我们已经有了一个能够表示部分正确输入的AST。 这就是你所需要的

从概念上讲,我会尝试将光标位置映射回相应的AST节点,并将其传递给完成引擎中的分析。当然,如果您的类型系统很大或者范围规则是这样的,那么构建符号表是昂贵的,考虑通过用AST节点缓存符号表来优化。p>
关于复杂性的一点注记 当您尝试以增量方式更新该信息,或避免在“虚假状态”上丢失“昂贵”状态时,事情会变得复杂起来(例如,如果用户只输入平衡作用域的开始部分,则销毁语义信息将是浪费,即使用户可能会立即关闭作用域继续)

小心地提前计划你准备承受的复杂程度。可以说“这超出了范围”。事实上,这总比你对我当时的第一反应发表评论要好:

嗯,Intellisense女士也在丢失无效代码,20%的案例仍然存在;-)[…]–PiotrK


我支持我的回答,我希望你意识到这基本上是相同的回答。如果您有资源/解决方案,您可以选择处理任意数量的复杂性。但始终要确保你能看到你的出发点和责任的落脚点。

你说得对,我把语法分析和语义分析搞砸了。谢谢,这两个步骤应该分开;)
struct annotation_t
{
    typedef void              result_type;
    hints_t* hints;

    template<typename first_t, typename last_t>
    void operator()(ast::type_t id, first_t f, last_t l) const
    {
        if (hints)
        {
            source_t loc(&*f, l - f);
            if (loc.size() > 0)
            {
                auto inserted = hints->annotations.emplace(loc, id);
                if (!inserted.second) inserted.first->second = id;
            }
        }
    }
};
::boost::phoenix::function<annotation_t> annotate{annotation_t{hints}};
on_success(lang_text, annotate(ast::type_t::lang_text, ::boost::spirit::qi::_1, ::boost::spirit::qi::_3));
class member_provider_t
{
     public: virtual ~member_provider_t() {}
     public: virtual std::vector<std::string> possible_identifiers_after(...) = 0;
}
schema://main.menu.screen/show/ab... (suggest: about*)