2017-04-19 17 views
2

Ich implementiere einen Relationale Algebra zu SQL-Konverter mit Peg.js. Ich habe fast alle Aktionen implementiert, aber ich implementiere den Assignment-Operator nicht, bei dem eine Relation in SQL konvertiert und in einer Variablen gespeichert wird, um sie später zu verwenden. (Bsp .: A < - ID (Clients)).Speichern Sie Variablenwert für die zukünftige Verwendung auf peg.js

Da der ursprüngliche Code mehr als 200 Zeilen enthält, werde ich ein einfaches Beispiel mit erklären, was ich dachte, um diese Regel zu erfassen.

-Code des Parsers:

{ 
    var variables = []; 
    console.log(variables); 
    function save(chave, value, rest){ 
      console.log("save", chave, value); 
      variables[chave] = value; 
      return rest; 
    } 

    function get(chave){ 
     console.log("get", chave); 
     return variables[chave]; 
    } 

} 


start 
    = _ id:Identificador _ "=" _ val:Integer _ [\n]* _ rest:start 
    {save(id,val);} 
/_ val:Integer _ {return val;} 
/_ id:Identificador _ {console.log(id, variables[id]); return get(id);} 


Identificador "identificador" 
    = [a-zA-Z]+ {return text();} 
Integer "integer" 
    = [0-9]+ { return parseInt(text(), 10); } 

_ "whitespace" 
    = [ \t\r]* 

Eingabebeispiel:

A = 23 
B = 45 
A 

Zu Beginn meines Parser, ich ein Array erstellt, um die Werte zu speichern gespeichert werden, was wäre, Zugriff über den Variablennamen.

In meiner ersten Regel habe ich angegeben, dass jeder Bezeichner, gefolgt von dem Zuweisungsoperator (in meinem Beispiel ist das Gleichheitszeichen), dann durch den Wert gespeichert wird (der in dem Beispiel eine ganze Zahl ist), gefolgt von ein Zeilenumbruch und dann für den Rest des Textes, würde es ein Speichern im Array geben, den Identifizierer als Schlüssel und seinen Wert speichern und den Rest der Abfrage verarbeiten.

In der letzten Zeile der ersten Regel habe ich erklärt, dass jede Zeile, die nur die alphabetische Kennung enthält, durch ihren gespeicherten Wert ersetzt würde. Im Beispiel sollte der Parser den Wert 23 zurückgeben, der dem Wert von Variable A zugewiesen wurde.

Der Parser gibt jedoch zurück. Ich habe die Webkonsole überprüft und festgestellt, dass die Reihenfolge der Ausführung falsch ist.

Console after running the parser

Gibt es eine Möglichkeit, die genaue Reihenfolge der Ausführung zu setzen? Ich wollte, dass der Parser den gefundenen Wert speichert, bevor der Rest des Textes verarbeitet wird.

+0

Sollten nicht 'Variablen' ein Objekt anstelle eines Arrays verwenden? –

+0

@JoshVoigts, würde den Typ der 'Variablen' zum Objekt ändern, und jeder Zusatz würde eine neue Eigenschaft hinzufügen? –

+0

Das scheint so, als würde es Sinn ergeben, da es in jedem Kontext nur _one_ Variable mit diesem Namen geben kann. –

Antwort

0

Ich bin mir nicht sicher, wie Peg zu machen die Reihenfolge der Auswertung umgekehrt, aber Sie könnten alle Ausdrücke auf einen Stapel werfen und dann in umgekehrter Reihenfolge auswerten. Versuchen Sie dies:

{ 
    var stack = []; 
    var result = null; 

    var variables = {}; 
    console.log(variables); 
    function save(chave, value, rest){ 
      console.log("save", chave, value); 
      stack.push(()=>{variables[chave] = value}); 
      return rest; 
    } 

    function get(chave){ 
     console.log("get", chave); 
     stack.push(()=>{result = variables[chave]}); 
    } 

    function evalStack() { 
     for (var i = stack.length - 1; 0 <= i; i--) { 
      stack[i]() 
     } 
     return result; 
    } 
} 


start 
    = expr 
    {return evalStack();} 

expr 
    = _ id:Identificador _ "=" _ val:Integer _ [\n]* _ rest:expr 
    {save(id,val);} 
/_ val:Integer _ {return val;} 
/_ id:Identificador _ {console.log(id, variables[id]); return get(id);} 


Identificador "identificador" 
    = [a-zA-Z]+ {return text();} 
Integer "integer" 
    = [0-9]+ { return parseInt(text(), 10); } 

_ "whitespace" 
    = [ \t\r]* 
+0

Wenn Sie Ihre Idee haben, speichert Ihr Code die Anweisungslesereihenfolge (von der letzten Zeile bis zur ersten Zeile) unter Verwendung der neuen ECMAScript-Lambda-Notation. Führen Sie dann einfach vom letzten Index des Arrays zum ersten Index und die richtige Reihenfolge ein. Eine ausgezeichnete und elegante Lösung. Vielen Dank. –

Verwandte Themen