-1

Ich würde gerne wissen, wie Ausdrücke analysiert werden, wenn mit Kontrollfluss gemischt werden.Mischen mathematischer Ausdruck mit Kontrollfluss

Lassen Sie uns solche Syntax annehmen:

case 
    when a == Method() + 1 
    then Something(1) 
    when a == Other() - 2 
    then 1 
    else 0 
end 

Wir haben hier zwei bedingte Ausdrücke bekam, Method() + 1, Something(1) und 0. Jeder kann durch Shunting-yard algorithm in Postfix übersetzt und dann leicht in AST übersetzt werden. Aber ist es möglich, diesen Algorithmus auch auf den Kontrollfluss anzuwenden? Oder gibt es andere Ansätze, um eine solche Mischung von Ausdrücken und Kontrollflüssen zu lösen?

ein weiteres Beispiel:

a == b ? 1 : 2 

auch, wie kann ich klassifiziere solcher Ausdruck: a between b and c, kann ich sagen, dass between drei Argumente Funktion? Oder gibt es einen speziellen Namen für solche Ausdrücke?

+2

Was genau meinen Sie mit "Kontrollfluss" hier? '... zwischen ... und ...' hört sich nicht wirklich so an, wie ich es mir als Kontrollfluss-Konstrukt vorstelle. Meinst du nur "ternärer Operator"? – sepp2k

+0

Sie haben Recht, ich sollte nicht Kontrollfluss Satz verwenden. Ich bin mir nicht sicher, wie ich solche Ausdrücke klassifizieren soll. Es ist kein ternärer Operator, denke ich, wie würdest du es nennen? – Puchacz

+1

'a zwischen b und c' hat drei Argumente und es ist ein Ausdruck, der einen Booleschen Wert ergibt. Es ist ein ternärer Operator. – EJP

Antwort

2

Sie können den ternären Operator mit einer Operator-Präzedenzgrammatik parsen. In

expr ? expr : expr 

der binären "Operator" hier ist ? expr :, die bequem beginnt und endet mit einem Operator Token (wenn auch verschiedenen). Um den Rangierbahnhof an diesen anzupassen, weisen Sie die Priorität zu? und der links-Vorrang von : zum Vorrang des ?: Operators. Die linke Priorität von ? und die Rechtspriorität von : sind & plusmn; ∞, genau wie Klammern (die sie tatsächlich sind).

Da die case Anweisung ist grundsätzlich Anwendung der ternären Operator wiederholt, mit leicht unterschiedlichen Schreibweisen für die Token, und ergibt sich zu einer ähnlichen Lösung. (Hier case when und end sind rein parenthetic, während then und die restlichen when s ? und : entsprechen.)

gesagt haben, dass es wirklich einfacher ist es, eine LALR (1) Parser-Generator zu verwenden, und es ist fast sicher eine verfügbare welcher Sprache Sie schreiben


Es ist klar, dass sowohl die ternäre Operator und Fall Aussage des OP Operator Grammatiken sind.

  1. Ternary Betreiber:

    ternary-expr: non-ternary-expr 
          | non-ternary-expr '?' expr ':' ternary-expr 
    

    Normalerweise wird der ternäre Operator niedrigere Priorität von einem anderen Betreiber und Mitarbeiter auf der rechten Seite, das ist, wie die oben geschrieben wird. In C und anderen Sprachen haben ternäre Ausdrücke den gleichen Vorrang wie Zuweisungsausdrücke, die einfach hinzugefügt werden können.Das ergibt die Beziehungen

    • X ·> ?
    • ? <· X
    • ? ·=· :
    • X ·> :
    • : <· X
  2. Case-Anweisung (eine von vielen möglichen Formulierungen):

    case_statement: 'case' case_body 'else' expr 'end' 
    case_body: 'when' expr 'then' expr 
         | case_body 'when' expr 'then' expr 
    

    Hier sind die Vorgänger-Beziehungen für die obige Grammatik:

    • case <· when
    • case ·=· else
    • when <· X (siehe unten)
    • when ·=· then
    • then ·> when
    • then ·> else
    • else <· X
    • else ·=· end
    • X ·> then
    • X ·> when
    • X ·> end

    X in den obigen Beziehungen beziehen sich auf jeden binären oder unärer Operator, jeder Wert Terminal, ( und ).

    Es ist einfach, Funktionen für die linke und rechte Priorität für alle diese Terminals zu finden; das Muster wird ähnlich dem von Klammern in einer algebraischen Standardgrammatik sein.

+0

Dies ist nicht wirklich eine genaue Antwort auf die Frage. Die Frage bezieht sich auf Kontrollflussanweisungen und -ausdrücke, wie im Titel angegeben, und in der Frage gibt es eine Fallanweisung. Sie können diese nicht mit einem Operatoren-Precedence-Parser analysieren. – EJP

+0

@EJP: Sie können absolut.Es handelt sich eindeutig um eine Operator-Grammatik, da keine Produktion zwei aufeinanderfolgende Nicht-Terminals hat und die Präzedenzrelationen leicht abzuleiten sind. Ich werde sie in meine Antwort aufnehmen, wenn Sie das für nützlich halten. – rici

2

Der Shunting-Yard-Algorithmus ist für Ausdrücke mit unären und binären Operatoren gedacht. Sie benötigen etwas leistungsfähigeres wie LL (1) oder LALR (1), um Kontrollflussanweisungen zu analysieren, und sobald Sie das haben, wird es auch Ausdrücke handhaben. Keine Notwendigkeit für den Shunting-Yard-Algorithmus überhaupt.

+0

Dies ist nicht wirklich eine genaue Antwort auf die Frage, obwohl ich zustimme, dass OP LALR (1) verwenden sollte. Aber ternäre Operatoren und '(cond ...)' - Typ-Konstruktionen, (worum OP eigentlich bittet), sind sicherlich dem Operator-Precedence-Parsing zugänglich. – rici

+0

@rici Dies ist nicht wirklich ein genauer Kommentar zu meiner Antwort. Ich habe nicht gesagt, dass man ternäre Operatoren nicht mit einem Operatoren-Precedence-Parser analysieren kann. Die Frage bezieht sich auf Steuerflussanweisungen und -ausdrücke, und in der Frage gibt es eine Fallanweisung. Sie können diese nicht mit einem Operatoren-Precedence-Parser analysieren. – EJP

Verwandte Themen