2010-12-18 15 views
2

Ich habe eine Sprache mit Aussagen von 4 Arten: S00, S01, S10, S11, wo eine führende 1 bedeutet Anfangsschlüsselwort, eine abschließende 1 bedeutet beendet, und ich habe ein Trennzeichen ";". Ich kann jede Aussage mit ";" beenden. Ich würde gerne eine Sprache parsen, die eine Liste von Aussagen erlaubt, die eine minimale Verwendung von ";" erlaubt. Der Parser ist Dypgen, was GLR + ist.Parse-Liste mit minimalen Trennzeichen

Beispiel:

{ x=1 fun f(){} x=1; x=1 var x=1 var x=1; x=1 } 

Ist es möglich, dies überhaupt zu tun? Wenn das so ist, wie? Wenn nicht, warum?

Ich glaube, es kann nicht getan werden, vor allem weil ich nicht darüber nachdenken kann, wie es geht :) Allerdings scheint es kontextsensitiv: die Regel ist, müssen Sie ein ";" zwischen A und B, wenn A nicht beendet ist und B nicht eingeleitet wird, dito für B und C, was bedeutet, dass B zweimal verwendet wird.

jedoch, weil der Parser GLR ist + ist es verlockend, nur

(s00|s01|s10|s11}* 

als Regel zu verwenden, und wenn es misparses werfen in einem „;“ (was ein s11 no-op ist), um die Mehrdeutigkeit aufzulösen. Es wäre schöner, wenn der Parser einen Syntaxfehler melden würde. Vielleicht könnte dies getan werden, wenn alternative s-Produktionen zusammengeführt werden. Das eigentliche Problem ist, wenn sie sich überschneiden anstatt zu verschmelzen: In diesem Fall könnte ein Programm-Parse explodieren.

Antwort

1

Ich hatte vor kurzem ein ähnliches Problem mit Top-Level-Phrasen, einige von ihnen brauchen eine abschließende ;; in der vorherigen Phrase und andere (beginnend mit einer Phrase Einführung Schlüsselwort) nicht. Ich habe mein Problem gelöst, indem ich die syntaktische Kategorie von Phrasen in zwei Teile aufspaltete und den Phrasensequenzen, die dieses Verhalten ausdrücken, feine Regeln gab. Dies führte jedoch zu Doppelungen in der gespaltenen Grammatik.

In Ihrem Fall wäre es so etwas wie:

sequence: 
    | (s00 | s10) sequence_closed 
    | (s01 | s11) sequence_open 
    | ε 

sequence_closed: 
    | s10 sequence_closed 
    | s11 sequence_open 
    | ';' sequence_open 
    | ε 

sequence_open: 
    | s00 sequence_closed 
    | s01 sequence_open 
    | ε 

Es ist ein bisschen komplizierter, wenn Sie überflüssige Trennzeichen zulassen wollen (und Sie wahrscheinlich wollen), aber das ist die Idee.

+0

Ah .. hmm .. Abgesehen von der hässlichen Tatsache habe ich Listen auf oberster Ebene mit der gleichen Syntax wie innere Listen, also müsste ich die Duplizierung duplizieren .. das sieht eigentlich ganz gut aus. Ich würde es hassen, dies für jede "listenähnliche Struktur" in der Sprache tun zu müssen, aber die wirkliche Sorge ist, dass die Statement-Level-Syntax sauberer aussieht: rein ästhetisch oder eifersüchtig (wenn Haskell und Ocaml ohne Separatoren auskommen, die ich möchte gut :) – Yttrill

+0

BTW: die ";;" Die Dinge legen nahe, dass Sie MLing sind, also überlegen Sie, dass Text der obersten Ebene nicht in eine Funktion gehoben werden kann, in der Sie nur ein ";" Stattdessen: In Ocaml ist das scheiße! Der einzige Grund, ";;" ist für REPL, um eine Aktion zu erzwingen, die ";" würde nicht. – Yttrill