2012-04-12 9 views
0

Gibt es eine bekannte Parser-Beschreibungssprache (wie Backus-Naur), die Wiederholungen erlaubt, bei denen die Anzahl der Wiederholungen aus dem Token-Stream extrahiert wird? Gibt es für Bonuspunkte C++ - Bibliotheken, die diese Syntax unterstützen?Parser-Beschreibung mit Wiederholung "Meta-Token"

Beispiel:

Lässt die "Meta-Token" # aufrufen, dann für eine Beschreibungssprache Ich bin auf der Suche, die eine Produktionsregel der folgenden Form behandeln würde:

RULE = # EXPRESSION 

As:

RULE = '1' EXPRESSION 
    | '2' EXPRESSION EXPRESSION 
    | '3' EXPRESSION EXPRESSION EXPRESSION 
    | '4' EXPRESSION EXPRESSION EXPRESSION EXPRESSION 
    | ... 

Beachten Sie, dass die Zähler tatsächliche Zeichenliterale sind. Dies steht im Gegensatz zu augmented Backus-Naur form, wo wir Regeln der Form haben kann:

RULE = 2*3EXPRESSION 

Welche sind äquivalent zu:

RULE = EXPRESSION EXPRESSION 
    | EXPRESSION EXPRESSION EXPRESSION 

Antwort auf dgarant:

Ich bin mir nicht sicher, das ist ganz was ich möchte. Ich denke etwas entlang der folgenden Zeilen:

int i; 

bool r = phrase_parse(first, last, 
    (
     int_[ phoenix::ref(i) = _1] >> repeat(i)[/*EXPRESSION*/] 
    ) 
    space); 

Noch wichtiger, obwohl ich auf ein formalisiertes Schema gehofft hatte, das diese Idee beschreiben könnte. Auf einem Seitenknoten braucht Spirit einiges, aber es ist ziemlich beeindruckend. Ich bin ein Fan.

Antwort

0

Ich kann nicht an eine formale Sprache denken, die rule = # EXPRESSION ermöglicht, Wiederholung anzugeben, wobei # ein Zeichenliteral ist. Meiner Meinung nach sollte es kein Problem sein, die formale Sprachspezifikation zu missbrauchen, vorausgesetzt, Sie machen einen Kommentar, um zu verdeutlichen, was Sie meinen. Wenn Sie wirklich an Standards halten möchten, können Sie das folgende in ABNF tun:

rule = '3' 3EXPRESSION 
    | '4' 4EXPRESSION 
    | '5' 5EXPRESSION 

Es sieht nicht genau wie das, was Sie wollen, aber es wird die Arbeit getan.

Ich glaube, boost::spirit::qi kann Ihren Anforderungen für das Parsing entsprechen. Schauen Sie sich die repeat directive an.

Geist Ihnen erlauben würde, Regeln zu schreiben, wie

rule = char_("'") >> int_[qi::_a = qi::_1] >> char_("'") >> repeat(qi::_a)[EXPRESSION] 

Wenn Sie daran interessiert sind, die Anzahl der Wiederholungen zu bestimmen, die analysiert wurden, können Sie eine weitere Aktion von der Regel anfügen können: [phoenix::ref(pCt) = qi::_a]

std::vector<double>& v; 
int pCt; 

bool r = phrase_parse(first, last, 
     (
      // to parse a collection of double expressions 
      char_("'") >> int_[qi::_a = qi::_1] >> char_("'") >> repeat(qi::_a)[double_[push_back(phoenix::ref(v), _1)]] 
      [phoenix::ref(pCt) = qi::_a] 
     ) 
     space); 
// assuming the parse was successful 
std::cout << "Parsed " << pCt << " elements" << std::endl; 

Der Stil von Spirit :: Qi Parsern braucht eine Weile, um sich daran zu gewöhnen, aber sie sind sehr mächtig, da Sie sie direkt in Ihren Code integrieren können.

+0

Ich habe oben einen Kommentar hinzugefügt. – tgoodhart

+0

@tgoodhart Ich habe meine Antwort aktualisiert. Ich kann mir keinen Sprachstandard vorstellen, der genau das macht, wonach Sie suchen. –