Ich versuche, eine Syntax Analyzer in Java (mit CUP) zu erstellen, die dieses Stück Code erkennen konnte:Wie definiert man eine Syntax, die mehrere Gedankenstriche für verschachtelte "if" Anweisungen verwendet?
if ¿b? then
~ a = 2;
~ if ¿b && c? then
~ ~ a = 3;
else
~ a = 4;
verwendet Meine Produktionen der "if" Anweisung das sind die folgen:
Instr ::= ...
| IF CONOP Exp:e CONCL THEN CondInstrList:l
...
;
...
CondInstrList ::= CondInstrList CondInstr
| /*empty*/
;
...
CondInstr ::= CONTROLD Instr
| CONTROLD CondInstr
;
wobei Instr für Anweisung/Anweisung steht, CondInstrList für Bedingte Anweisungsliste steht und CONTROLD für Control Dash (~) steht. (CONOP und CONCL bedeuten Zustand Öffnen/Schließen)
Das Problem ist, dass mit dieser Grammatik, die erzeugte AST ist wie folgt:
if
|-condition b
|-condInstrListT
|---asig a = 2
|---if
|---condition b and c
|---condInstrListT
| |---asig a = 2
|---condInstrListF
|---asig a = 4
und so wird die „else“ Teil in Verbindung mit dem inneren " ob".
Ich weiß einfach nicht, wie man eine Grammatik schreibt, die respektiert, wie ich meine Sprache haben möchte.
Jede Hilfe wird geschätzt.
Ich kann mehr Details geben, wenn nötig.
Das ist genau die Lösung. Jetzt habe ich ein Problem mit JLex. Ich speichere die Einrückungsebene in einem Attribut mit dem Namen "Einzug" und jedes Ende der Zeile setze den Zähler der tatsächlichen Einrückungsebene (Attribut "Ist") auf 0. Dies ist der Fall, wenn ein Strich mehr als die tatsächliche Einrückungsebene ist Ich gebe ein INDENT-Symbol zurück. Das Problem tritt auf, wenn ich die OUTDENT zurückgeben muss. Ich kann einfach nicht herausfinden, wie es geht, da JLex nur einen Wert zurückgibt. Ich kann herausfinden, wie viele "Einrückungslevel" ich subtrahieren muss, aber ich habe keine Möglichkeit so viele OUTDENT-Symbole wie nötig zurückzugeben. –
Ich denke, Sie müssten in der Lage sein, Eingaben erneut zu lesen, um die korrekten OUTDENT-Tokens direkt im lexikalischen Analysator zu generieren, und ich habe keinen Beweis gesehen, dass JLex das tun kann. Sie werden wahrscheinlich eine Zwischenschicht zwischen dem Parser und dem lexikalischen Analysator haben müssen, die Informationen über die Einrückungslevel jeder Zeile vom lexikalischen Analysator erhalten und die richtige Anzahl von IDENT- oder OUTDENT-Tokens herausfinden kann, die an den Scanner zurückgegeben werden. –
Dieser letzte Satz sollte "... Token lesen, um zum ** Parser ** zurückzukehren". –