提升精神递归解析
boost spirit recursive parsing
我已经阅读了有关递归解析的其他主题,但这些解决方案对我来说还不够。
让我们拥有这样一个简单的解析器:
struct B;
typedef boost::variant<int, boost::recursive_wrapper<B> > A;
struct B {
B() {
static int l = 0;
cout << "B() " << ++l << endl;
}
A a1;
A a2;
};
// fusion adapt structs ....
typedef std::string::iterator iter;
typedef rule<iter, B()> BRule;
typedef rule<iter, A()> ARule;
ARule a;
BRule b;
a %= b | int_;
b %= a >> lit(',') >> a;
std::string s("5,8,3,1");
iter be = s.begin();
iter en = s.end();
B u;
parse(be, en, b, u);
我想解析类似 's' 字符串的内容:“5,1,3,9” - 这应该由 B 元素组成,其中包含 2 个仅包含整数的 B 元素。
它导致 - 根据网站名称 - 堆栈溢出。
当我添加括号时:
b %= '(' >> a >> lit(',') >> a >> ')';
std::string s("((5,8),(3,1))");
...一切正常。
是否有可能避免括号并以这种方式使用解析器:
a %= b ....
b %= a ...
??
不一定是这样的表示法,但用于解析 '3,4,5,6' 而不是 '((3,4),(5,6))'
不,你不能那样做。
PEG 解析器将简单地在这两个规则之间来回跳转。
为什么你的解析器不简单:
b %= int_ >> *(lit(',') >> int_);
或者,您会经常看到以下形式的结构:
expression %= primary >> *(lit(',') >> primary);
primary %= '(' >> expression >> ')' | int_;
您也可以使用 list parser 并将其写为:
expression %= primary % lit(',');
primary %= '(' >> expression >> ')' | int_;
当然,对于逗号分隔的数字,
a %= b % ','
更好,但这只是一个用来说明问题本质的假例子。
如上所写,解决方案是:
a %= b ....
b %= any_rule_that_consumes_input >> .... a ....
我已经阅读了有关递归解析的其他主题,但这些解决方案对我来说还不够。
让我们拥有这样一个简单的解析器:
struct B;
typedef boost::variant<int, boost::recursive_wrapper<B> > A;
struct B {
B() {
static int l = 0;
cout << "B() " << ++l << endl;
}
A a1;
A a2;
};
// fusion adapt structs ....
typedef std::string::iterator iter;
typedef rule<iter, B()> BRule;
typedef rule<iter, A()> ARule;
ARule a;
BRule b;
a %= b | int_;
b %= a >> lit(',') >> a;
std::string s("5,8,3,1");
iter be = s.begin();
iter en = s.end();
B u;
parse(be, en, b, u);
我想解析类似 's' 字符串的内容:“5,1,3,9” - 这应该由 B 元素组成,其中包含 2 个仅包含整数的 B 元素。
它导致 - 根据网站名称 - 堆栈溢出。 当我添加括号时:
b %= '(' >> a >> lit(',') >> a >> ')';
std::string s("((5,8),(3,1))");
...一切正常。
是否有可能避免括号并以这种方式使用解析器:
a %= b ....
b %= a ...
?? 不一定是这样的表示法,但用于解析 '3,4,5,6' 而不是 '((3,4),(5,6))'
不,你不能那样做。 PEG 解析器将简单地在这两个规则之间来回跳转。
为什么你的解析器不简单:
b %= int_ >> *(lit(',') >> int_);
或者,您会经常看到以下形式的结构:
expression %= primary >> *(lit(',') >> primary);
primary %= '(' >> expression >> ')' | int_;
您也可以使用 list parser 并将其写为:
expression %= primary % lit(',');
primary %= '(' >> expression >> ')' | int_;
当然,对于逗号分隔的数字,
a %= b % ','
更好,但这只是一个用来说明问题本质的假例子。
如上所写,解决方案是:
a %= b .... b %= any_rule_that_consumes_input >> .... a ....