这实际上是在我上一个问题之后建立的:
How to provider user with autocomplete suggestions for given boost::spirit grammar?
在Sehe解决方案中,我为语法着色添加了注释器:
首先通过采用hints
结构(注意:ast_type_t
是enum class
):
template <class ast_type_t> class hints_t
{
struct by_location_t
{
template<typename T, typename U> bool operator()(T const& a, U const& b) const
{
if(loc(a) == loc(b)) return size(a) > size(b);
return loc(a) < loc(b);
}
private:
static location_t loc(source_t const& s)
{
return s.begin();
}
static location_t loc(location_t const& l)
{
return l;
}
static std::size_t size(source_t const& s)
{
return s.end() - s.begin();
}
static std::size_t size(location_t const& s)
{
return 1;
}
};
public:
std::map<location_t, std::string, by_location_t> incomplete;
std::map<source_t, candidates_t, by_location_t> suggestions;
std::map<source_t, ast_type_t, by_location_t> annotations;
operator bool() const
{
return incomplete.size() || suggestions.size();
}
};
然后通过添加注释器本身:
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));
通常可以,但是我遇到了另一个路障。我需要自动补全功能,它实际上可以根据先前解析的值构建动态建议列表;最好的例子是在原始问题的评论中使用foo.member1.member2
。我不允许在已解析文本本身内部不允许成员定义,它们始终由外部C ++类提供;
此类C ++类的示例:
class member_provider_t
{
public: virtual ~member_provider_t() {}
public: virtual std::vector<std::string> possible_identifiers_after(...) = 0;
}
现在变得棘手-我想将整个解析结果(到现在为止)传递到...
占位符(以ast解析的形式)。示例:解析自定义架构的uri:
schema://main.menu.screen/show/ab... (suggest: about*)
(** about
-取决于到目前为止已解析的整个URL)
如果这不可能,那么任何其他将尽可能多的已解析部分传递给提供程序功能的方法都适合我。
答案 0 :(得分:1)
关于语法突出显示,您看到了吗?
关于上下文相关完成问题的第二部分,您只需要语义分析。这里要记住的最重要的事情是将解析和语义分析分开以简化您的生活。
在original answer中,我们已经有了一个AST,能够表示部分正确的输入。 这就是您所需要的。
从概念上讲,我将尝试将光标位置映射回相应的AST节点,并将其传递给完成引擎中的分析。当然,如果您的类型系统很大,或者作用域规则太长,以至于建立符号表非常昂贵,请考虑通过使用AST节点缓存符号表来进行优化。
当您尝试逐步更新该信息或避免在“虚假状态”上丢失“昂贵”状态时,事情变得复杂(例如,如果用户仅进入平衡范围的开始部分,则破坏语义信息,即使用户可能会通过关闭范围立即继续操作。)
请谨慎规划要准备携带的复杂程度。可以说“超出范围”。实际上,总比在那时对我的第一个回复发表评论时要好得多:
嗯,MS Intellisense也因无效代码而丢失,仍有20%的案例;-) [...] – PiotrK Nov 17 '17 at 19:40
我支持我的答复,希望您意识到这基本上是相同的答复。如果您有足够的资源/解决方案,则可以选择解决任意数量的复杂性。但是,请始终确保您尝试查看正在启动的东西以及降压的地方。