保存变量值以备将来使用 peg.js
Save variable value for future use on peg.js
我正在使用 Peg.js 实现关系代数到 SQL 的转换器。我实现了几乎所有的操作,但我没有实现赋值运算符,其中一个关系被转换为 SQL 并保存在一个变量中以备将来使用。 (例如:A <- Π id(客户))。
由于原始代码有 200 多行,我将 post 一个简单的示例来解释我想捕获此规则的内容。
解析器代码:
{
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]*
输入示例:
A = 23
B = 45
A
在我的解析器开始时,我创建了一个数组来存储要保存的值,通过变量名访问。
在我的第一条规则中,我声明每个标识符,后跟赋值运算符(在我的示例中是等号),然后是要保存的值(在示例中是整数),然后是通过换行然后对于文本的其余部分,将在数组中进行保存,将标识符存储为键及其值,并处理查询的其余部分。
在第一条规则的最后一行,我声明任何只包含字母标识符的行都将被其存储的值替换。在示例中,解析器应该 return 值 23,这是分配给变量 A 的值。
但是解析器正在 returning undefined
。我检查了 Web 控制台,发现执行顺序不正确。
Console after running the parser
有没有办法设置准确的执行顺序?我希望解析器在处理其余文本之前保存找到的值。
我不确定如何让 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]*
我正在使用 Peg.js 实现关系代数到 SQL 的转换器。我实现了几乎所有的操作,但我没有实现赋值运算符,其中一个关系被转换为 SQL 并保存在一个变量中以备将来使用。 (例如:A <- Π id(客户))。
由于原始代码有 200 多行,我将 post 一个简单的示例来解释我想捕获此规则的内容。
解析器代码:
{
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]*
输入示例:
A = 23
B = 45
A
在我的解析器开始时,我创建了一个数组来存储要保存的值,通过变量名访问。
在我的第一条规则中,我声明每个标识符,后跟赋值运算符(在我的示例中是等号),然后是要保存的值(在示例中是整数),然后是通过换行然后对于文本的其余部分,将在数组中进行保存,将标识符存储为键及其值,并处理查询的其余部分。
在第一条规则的最后一行,我声明任何只包含字母标识符的行都将被其存储的值替换。在示例中,解析器应该 return 值 23,这是分配给变量 A 的值。
但是解析器正在 returning undefined
。我检查了 Web 控制台,发现执行顺序不正确。
Console after running the parser
有没有办法设置准确的执行顺序?我希望解析器在处理其余文本之前保存找到的值。
我不确定如何让 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]*