2015-04-02 32 views
1

我已阅读关于递归解析的其他主题,但这些解决方案对我来说是不够的。助推精神递归解析

让我们有这样一个简单的解析器:

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); 

我想分析类似的'字符串:“5,1,3,9” - 这应该包括其中包含2组B的元素B族元素其中只包含整数。

它导致 - 根据站点名称 - 堆栈溢出。 当我添加父母:

b %= '(' >> a >> lit(',') >> a >> ')'; 
std::string s("((5,8),(3,1))"); 

...一切工作正常。

是否有可能避免parenthises和使用的解析器INT此方式:

a %= b .... 
b %= a ... 

? 不一定这样一个符号,但对于分析 '3,4,5,6',而不是 '((3,4),(5,6))'

回答

1

不,你不能这样做。 PEG解析器将简单地在这两个规则之间来回跳动。

为什么不只是你的解析器:

b %= int_ >> *(lit(',') >> int_); 

或者,你会经常看到形式的构造:

expression %= primary >> *(lit(',') >> primary); 
primary %= '(' >> expression >> ')' | int_; 

你也可以使用一个list parser和写为:

expression %= primary % lit(','); 
primary %= '(' >> expression >> ')' | int_; 
+1

技术上,精神是PEG – sehe 2015-04-02 15:05:41

0

当然,更好的是用逗号分隔的数字

a %= b % ','
,但这仅仅是一个展示问题本质的虚假例子。

作为写入,解决方案是:

 

    a %= b .... 
    b %= any_rule_that_consumes_input >> .... a ....