2015-04-02 34 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 ....