Javascript 保存变量值以备将来在peg.js上使用

Javascript 保存变量值以备将来在peg.js上使用,javascript,parsing,peg,pegjs,Javascript,Parsing,Peg,Pegjs,我正在使用Peg.js实现一个从关系代数到SQL的转换器。我实现了几乎所有的操作,但我没有实现assigment操作符,在这个操作符中,一个关系被转换为SQL并保存在一个变量中以备将来使用。(例如:A我不确定如何使peg反转求值顺序,但您可以将所有表达式放到堆栈上,然后按相反顺序求值。请尝试以下操作: { var stack = []; var result = null; var variables = {}; console.log(variables);

我正在使用Peg.js实现一个从关系代数到SQL的转换器。我实现了几乎所有的操作,但我没有实现assigment操作符,在这个操作符中,一个关系被转换为SQL并保存在一个变量中以备将来使用。(例如:A我不确定如何使peg反转求值顺序,但您可以将所有表达式放到堆栈上,然后按相反顺序求值。请尝试以下操作:

{
    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]*
{
var堆栈=[];
var结果=null;
var变量={};
console.log(变量);
函数保存(chave、value、rest){
console.log(“save”、chave、value);
stack.push(()=>{variables[chave]=value});
返回休息;
}
函数get(chave){
log(“get”,chave);
stack.push(()=>{result=variables[chave]});
}
函数evalStack(){

对于(var i=stack.length-1;0不应该使用对象而不是数组吗?@JoshVoigts,将
变量的类型更改为对象,并且每次添加都会添加一个新属性?这似乎是有意义的,因为在任何上下文中都只能有一个具有该名称的变量。亲爱的@JoshVoigts,我查将变量的类型设置为object,但其工作方式相同。但知道PEG在执行函数之前解释所有标记,导致在保存值之前访问键的值,我决定在解析器遇到这种情况时返回一个object。
=\id:Identifier\←" _ save:unionrelationship\uuuuunewline\urest:start{return{“type”:“attrib”,id:id,value:save,rest:rest};}
之后,我考虑创建一个后处理器来完成其余的翻译。你知道了,你的代码存储指令读取顺序(从最后一行到第一行),使用新的ECMAScript lambda表示法。然后,只需从数组的最后一个索引运行到第一个索引,即可获得正确的顺序。这是一个优秀而优雅的解决方案。谢谢。
A = 23
B = 45
A
{
    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]*