- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我遇到了 boost::spirit::qi
的问题。我定义了以下两个解析器:
struct attr_1 { std::string a; };
BOOST_FUSION_ADAPT_STRUCT(attr_1, (std::string, a))
struct attr_2 { double a; };
BOOST_FUSION_ADAPT_STRUCT(attr_2, (double, a))
struct grammar_1 : boost::spirit::qi::grammar<const char*, attr_1()> {
grammar_1() : grammar_1::base_type{rule_} {
rule_ = boost::spirit::qi::eps >> +boost::spirit::ascii::upper;
}
private:
boost::spirit::qi::rule<const char*, attr_1()> rule_;
};
struct grammar_2 : boost::spirit::qi::grammar<std::string::iterator, attr_2()> {
grammar_2() : grammar_2::base_type{rule_} {
rule_ = boost::spirit::qi::double_;
}
private:
boost::spirit::qi::rule<std::string::iterator, attr_2()> rule_;
};
现在,我想用前面的语法写第三个语法,如下:
typedef boost::variant<attr_1, attr_2> attr_comp;
struct grammar_comp : boost::spirit::qi::grammar<????, attr_comp()> {
grammar_comp() : grammar_comp::base_type{rule_} {
rule_ = (g1_ | g2_);
}
private:
grammar_1 g1_;
grammar_2 g2_;
boost::spirit::qi::rule<????, attr_comp()> rule_;
};
由于 grammar_1
和 grammar_2
具有不同的迭代器类型,我应该将哪种类型放在新语法的定义中?
这是一个(非编译)简化示例:
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/home/qi.hpp>
#include <boost/variant.hpp>
#include <string>
#include <sstream>
struct attr_1 { std::string a; };
BOOST_FUSION_ADAPT_STRUCT(attr_1, (std::string, a))
struct attr_2 { double a; };
BOOST_FUSION_ADAPT_STRUCT(attr_2, (double, a))
struct grammar_1 : boost::spirit::qi::grammar<const char*, attr_1()> {
grammar_1() : grammar_1::base_type{rule_} {
rule_ = boost::spirit::qi::eps >> +boost::spirit::ascii::upper;
}
private:
boost::spirit::qi::rule<const char*, attr_1()> rule_;
};
struct grammar_2 : boost::spirit::qi::grammar<std::string::iterator, attr_2()> {
grammar_2() : grammar_2::base_type{rule_} {
rule_ = boost::spirit::qi::double_;
}
private:
boost::spirit::qi::rule<std::string::iterator, attr_2()> rule_;
};
typedef boost::variant<attr_1, attr_2> attr_comp;
struct grammar_comp : boost::spirit::qi::grammar<????, attr_comp()> {
grammar_comp() : grammar_comp::base_type{rule_} {
rule_ = (g1_ | g2_);
}
private:
grammar_1 g1_;
grammar_2 g2_;
boost::spirit::qi::rule<????, attr_comp()> rule_;
};
int main() {
std::string s;
std::istringstream iss("3\n13.2\nCIAO\nFOOFOOfoo\n");
grammar_comp gg_;
attr_comp aa_;
while (std::getline(iss, s)){
auto it = s.begin();
if (boost::spirit::qi::parse(it, s.end(), gg_, aa_)) {
std::cout << s << std::endl;
std::cout << std::endl;
}
}
return 0;
}
最佳答案
您不能使用不同迭代器类型的子语法。出于显而易见的原因,您不会神奇地解析不同的输入集。
单个输入意味着单个输入迭代器范围。
只需将关于迭代器类型的决定推迟到顶层实例化器:
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/home/qi.hpp>
#include <boost/variant.hpp>
#include <sstream>
#include <string>
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
struct attr_1 {
std::string a;
};
BOOST_FUSION_ADAPT_STRUCT(attr_1, (std::string, a))
struct attr_2 {
double a;
};
BOOST_FUSION_ADAPT_STRUCT(attr_2, (double, a))
template <typename It = const char *> struct grammar_1 : qi::grammar<It, attr_1()> {
grammar_1() : grammar_1::base_type{ rule_ } { rule_ = qi::eps >> +ascii::upper; }
private:
qi::rule<It, attr_1()> rule_;
};
template <typename It = std::string::const_iterator> struct grammar_2 : qi::grammar<It, attr_2()> {
grammar_2() : grammar_2::base_type{ rule_ } { rule_ = qi::double_; }
private:
qi::rule<It, attr_2()> rule_;
};
typedef boost::variant<attr_1, attr_2> attr_comp;
template <typename It = std::string::const_iterator> struct grammar_comp : qi::grammar<It, attr_comp()> {
grammar_comp() : grammar_comp::base_type{ rule_ } { rule_ = (g1_ | g2_); }
private:
grammar_1<It> g1_;
grammar_2<It> g2_;
qi::rule<It, attr_comp()> rule_;
};
int main() {
std::istringstream iss("3\n13.2\nCIAO\nFOOFOOfoo\n");
grammar_comp<> gg_;
attr_comp aa_;
std::string s;
while (std::getline(iss, s)) {
auto it = s.cbegin();
if (qi::parse(it, s.cend(), gg_, aa_)) {
std::cout << s << std::endl;
std::cout << std::endl;
}
}
}
打印
3
13.2
CIAO
FOOFOOfoo
关于c++ - boost::spirit::qi 文法使用不同迭代器类型的文法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46202007/
我正在尝试实现一个表达式处理语法(处理嵌套括号和其他内容)。到目前为止我有以下内容,但它们无法处理某些情况(成功/失败情况出现在以下代码块之后)。有人知道这是怎么回事吗? 注意:varname +=
我在 ANTLR 语法中写下了以下语句: loopStatement : 'loop' (statement|exit)* 'end' 'loop' ';' ; 如果我没理解错的话,
为 C 的一个子集编写一个简单的 BNF 语法,它支持多个语句,包括赋值、if-else 和没有 block 语句的 while 语句。为你的非终结符使用有意义的名字(相对于神秘的字母)。假设变量由单
我正在尝试为以下语法创建一个 LALR(1) 解析器并发现一些移位/归约冲突。 S := expr expr := lval | ID '[' expr ']' OF expr lval := ID
根据这个paper的规则: If A is the start nonterminal, put EOF in FOLLOW(A) Find the productions with A on the
为 k > 1 制作人工 LR(k) 文法很容易: Input: A1 B x Input: A2 B y (introduce reduce-reduce con
在使用 make 和 bison 的项目中,我很难指定编译语法 grammar.tab.c 依赖于语法输入 grammar.y,每个目标文件都依赖于相应的源文件(包括 grammar.tab.o),并
我正在尝试从语法分析树中提取乔姆斯基范式 (CNF) - 句子的语法产生式: (ROOT (S (NP (DT the) (NNS kids)) (VP (VBD opened)
我知道 ANTLR 可以接受 LL(*) 文法。但是,有没有办法使用 ANTLR 检查语法是否是 LL(1)? 最佳答案 options { k = 1; } 如果您的语法不在 LL(1) 中,
我还没有找到答案。是否存在无法转换为 LL(1) 的上下文无关且无歧义的语法? 我发现了一个我不知道如何转换为 LL(1) 的作品:parameter-type-list C99中的生产: param
我是一名优秀的程序员,十分优秀!