CFG für Python-Stil Tupel

Nachdem ich für die zillerste Zeit eine Frage nach "Wie kann ich HTML mit Regex analysieren" auf Stackoverflow gelesen, bekam ich mich wieder in Grammatiken interessiert, packte meine Universitätsskripte und nach ein paar Minuten fragte ich mich, wie ich jemals meine Prüfungen bestanden habe.

Als einfach (gut, "einfach" erwarte ich es zu sein) Übung habe ich versucht, eine CFG zu schreiben, die gültige PythonTupel produziert (aus Gründen der Einfachheit nur mit den Bezeichnern a , b und c ). Nach einiger Zeit kam ich jetzt mit:

  • Einige NLP-Sachen mit Grammatik, Tagging, Stemming und Wort Sinne Disambiguierung in Python zu tun
  • Parsing Python mit PLY, wie man den Einzug und dedent Teil Code
  • Stack Overflow bei Pyparsing Ada 2005 Scoped Identifier mit Referenzhandbuch Grammatik
  • Wie wird die Python-Grammatik intern verwendet?
  • Implementierung des Parsers für die Markdown-Sprache
  • Habe ich einen Bug in meiner Grammatik oder das Parser-Generation-Tool?
  •  G = ( {Tuple, TupleItem, Id}, {“a”, “b”, “c”, “,”, “(“, “)”}, P, Tuple) 

    Sein P:

     Tuple → “(“ TupleItem “)” Tuple → “(“ TupleItem Id “)” Tuple → “(“ TupleItem Tuple “)” TupleItem → TupleItem TupleItem TupleItem → Id “,” TupleItem → Tuple “,” Id → “a” Id → “b” Id → “c” 

    Diese Grammatik soll z. B. (a,) , (a,b) , (a,b,) , ((a,),) ((a,b,),(a,),) , aber nicht (,a) , () (a,bc) usw. Ich möchte keine überflüssigen Klammern wie ((a),) oder ((a,b)) erzeugen. Eigentlich die manchmal optional (wenn mehr als ein Element) und manchmal obligatorisch (wenn nur ein Element) Schleppkomma fast getötet mich.

    1. Gibt es in dieser Grammatik alle gültigen Python-Tupel (mit nur a , b und c )?
    2. Gibt es in dieser Grammatik Saiten, die keine gültigen Python-Tupel sind?
    3. Ist diese Grammatik richtig? (Ich bin mir nicht sicher über das zyklische Kriterium)
    4. Warum ist meine Grammatik so langweilig? Wie kann ich die Anzahl der Produktionsregeln reduzieren? (Nicht mit syntaktischen Zucker wie Pfeifen, da diese nur mehrere Regeln auf eine Zeile setzen.)

    Vielen Dank im Voraus für Ihre Kommentare und Antworten.

  • Python für Loop verlangsamt und gleichmäßig hängt
  • Multiprocessing Pool hängt, wenn es eine Ausnahme in einem der Thread gibt
  • Pythons Subprocess.Popen-Objekt hängt das Sammeln von Child-Ausgabe, wenn der Child-Prozess nicht beendet wird
  • Scripts in virtualenv hängen unendlich (python 3.5, windows 7)
  • Python C-Programm-Unterprozess hängt bei "for line in iter"
  • Threading-Warteschlange hängt in Python
  • One Solution collect form web for “CFG für Python-Stil Tupel”

    Ohne mich auf die Python-Grammatik zu verweisen, bin ich mir ziemlich sicher, dass deine Grammatik alle gültigen Python-Tupel produziert, außer einem ( () , dem leeren Tupel), und dass es nichts produziert, was kein Python-Tupel ist. Also in diesem Ausmaß ist es gut

    Allerdings ist es nicht viel für das Parsing, weil

     TupleItem → TupleItem TupleItem 

    Ist exponentiell zweideutig. (Dicho sea de paso, TupleItem ist kein sehr beschreibender Name für dieses Nicht-Terminal, das ist wirklich eine Liste.) Ambiguous Grammatiken sind "richtig" in dem Sinne, dass sie alle Regeln für kontextfreie Grammatiken, aber eindeutige Grammatiken gehorchen Sind in der Regel besser.

    Es ist einfach zu beheben:

     Tuple → “(“ “)” Tuple → “(“ ItemList “,” “)” Tuple → “(“ ItemList “,” Item “)” ItemList → Item ItemList → ItemList “,” Item Item → Id Item → Tuple 

    (Ich habe die Id Produktionen ausgelassen, in praktischen Grammatiken wäre Id ein Terminal, aber es macht wenig Unterschied.)

    Schließlich, warum ist diese Grammatik "so lang"? (Sind sieben Produktionen wirklich "so langweilig?"? Abhängig von Ihren Kriterien, denke ich.)

    Die einfache Antwort ist, dass CFGs so sind. Sie könnten syntaktischen Zucker hinzufügen, um die rechten Seiten reguläre Ausdrücke (nicht nur Abwechslung, sondern auch Kleene Stern und seine Begleiter) zu machen:

     Tuple → “(“ [ ItemList “,” Item? ]? “)” ItemList → Item // “,” Item → Id | Tuple 

    Hier verwende ich den nützlichen interpolierten Operator // , der selten in akademischen Klassen gelehrt wird und folglich überraschend wenige Implementierungen hat:

    a // b = def a(ba) *

    Ob das oben ist leichter zu lesen ist, lass ich dem Leser zu. Es ähnelt dem EBNF (Extended Backus-Naur Form), das üblicherweise in Grammatikausstellungen verwendet wird, insbesondere in RFCs. (EBNF ist einer der wenigen Formalismen mit einem Interpolationsoperator, obwohl er nicht so ausdrücklich wie meine geschrieben ist.)

    Wie auch immer, ich glaube nicht, dass deine Grammatik getrimmt werden kann.

    Python ist die beste Programmiersprache der Welt.