2011-03-09 97 views
5

基本上我正在执行一个表达式解析器。因为我需要尽可能好的性能,并且根据文档的语法结构可能会非常慢,所以我希望在解析之前重新使用语法并绑定符号表。由于语法的客户端可能有一个符号表,它在解析之前构建和维护,我理想的情况是避免复制实际的表,因此我导致下面的代码(简化)用于翻译术语:在boost :: spirit中使用指向解析器的指针

qi::symbols< char, double >* m_Symbols; 
qi::rule< Iterator, double(), ascii::space_type > m_Val; 

m_Val = qi::int_[ _val = boost::phoenix::static_cast_<double>(boost::spirit::_1) ] | qi::double_ | m_Symbols; 

这里的问题是m_Symbols。我想要的是m_Val通过引用保存m_Symbols,因为当我们绑定符号表时,我自然会修改指针,我认为可以通过使用boost :: phoenix :: ref来以某种方式解决这个问题。但是更大的问题是,在合成新的分析器时,我似乎无法使用指针分析器。在表达式中使用解引用直接引用m_Symbols,这是不需要的,我想将解引用延迟到解析时间。

+0

这似乎是减少语法实例数量的错误方法。为什么不只是有一个静态/单例实例的语法,并使其不可复制? – ildjarn 2011-03-09 19:16:55

+0

不幸的是,我仍然必须在解析之前绑定符号表,这会导致相同的问题。 – Ylisar 2011-03-10 12:16:48

回答

2

我相信一个简单的

qi::symbols<char, double>* m_Symbols; 
qi::rule<Iterator, double(), ascii::space_type> m_Val; 

m_Val = qi::int_ | qi::double_ | qi::lazy(*m_Symbols); 

应该做你所需要的。 lazy解析器(请参阅here)仅在解析时间评估其参数(重复)。

+0

感谢您的帮助,真棒与专家帮助!可悲的是我已经尝试了这个解决方案,看起来似乎qi :: lazy()不太乐意接受这个表达式。我从MSVC 2008中得到以下错误:1> /main.cpp(75):error C2784:'proto :: terminal > :: type boost :: spirit :: lazy(const boost :: phoenix :: actor &)':无法为'const boost :: phoenix :: actor &'从'boost :: spirit :: qi :: symbols'推导出模板参数' 这使我相信m_Symbols在传递给lazy()之前被取消引用? – Ylisar 2011-03-10 10:48:32

+2

似乎下面的技巧:qi :: lazy(* boost :: phoenix :: val(boost :: phoenix :: ref(m_Symbols)))。 Val作为包装来缓解解引用,请确保指针不被复制。 – Ylisar 2011-03-10 12:40:09