Den*_*ink 5 php parser-generator lemon
我在创建一个简单的语法时遇到了麻烦,我支持函数调用.
我正在使用Greg的基于柠檬的PHP_ParserGenerator.
这是语法的相关部分:
program ::= expr(A). { $this->result = A; }
value(A) ::= SIMPLE_STRING(B). { A = B; }
value(A) ::= NUMBER(B). { A = B; }
value(A) ::= CONTEXT_REFERENCE(B). { A = B; }
arg_list ::= arg_list SEPARATOR value(B). { $this->args[] = B; }
arg_list ::= value(B). { $this->args[] = B; }
arg_list ::= .
expr(A) ::= SIMPLE_STRING(B) PAREN_LEFT arg_list PAREN_RIGHT. { A = call_user_func_array(B, $this->args); }
expr(A) ::= CONTEXT_REFERENCE(B). {
list($context, $key) = explode('.', B);
A = $this->context[$context][$key];
}
Run Code Online (Sandbox Code Playgroud)
当我使用上下文初始化解析器array('user' => array('name' => 'Dennis')); 并执行以下代码时:
$parser->doParse(PelParser::CONTEXT_REFERENCE, 'user.name');
$parser->doParse(0, 0);
Run Code Online (Sandbox Code Playgroud)
在$result"丹尼斯":如下是.生活很好.
但是当我提供一个CONTEXT_REFERENCE作为函数调用的参数时,它不起作用:
$parser->doParse(PelParser::SIMPLE_STRING, 'str_replace');
$parser->doParse(PelParser::PAREN_LEFT, '(');
$parser->doParse(PelParser::SIMPLE_STRING, 'e');
$parser->doParse(PelParser::SEPARATOR, ',');
$parser->doParse(PelParser::NUMBER, 3);
$parser->doParse(PelParser::SEPARATOR, ',');
$parser->doParse(PelParser::CONTEXT_REFERENCE, 'user.name');
$parser->doParse(PelParser::PAREN_RIGHT, ')');
$parser->doParse(0, 0);
Run Code Online (Sandbox Code Playgroud)
该$result是"us3r.nam3".不尽如人意.为了记录,预期的输出当然是'D3nnis'.(user.name 首先被字符串'Dennis'替换,然后传递给str_replace()函数).
我怀疑它与优先级有关.但我无法想象我应该做些什么才能做到这一点.非常稀疏的Lemon文档没有太大的帮助.
任何帮助将不胜感激!谢谢
我似乎找到了我的问题的答案。
当我将语法更改为:
program ::= expr(A). { $this->result = A; }
value(A) ::= SIMPLE_STRING(B). { A = B; }
value(A) ::= NUMBER(B). { A = B; }
value(A) ::= CONTEXT_REFERENCE(B). {
// B=='{context}.{name}'
list($context, $key) = explode('.', B);
A = $this->context[$context][$key];
}
arg_list ::= arg_list SEPARATOR value(B). { $this->args[] = B; }
arg_list ::= value(B). { $this->args[] = B; }
arg_list ::= .
expr(A) ::= SIMPLE_STRING(B) PAREN_LEFT arg_list PAREN_RIGHT. { A = call_user_func_array(B, $this->args); }
Run Code Online (Sandbox Code Playgroud)
它似乎按预期工作。
问题是我在第一个语法中产生了歧义:
value(A) ::= CONTEXT_REFERENCE(B). { A = B; }
expr(A) ::= CONTEXT_REFERENCE(B). {
list($context, $key) = explode('.', B);
A = $this->context[$context][$key];
}
Run Code Online (Sandbox Code Playgroud)
我将把问题和答案留在这里,以便其他人可以从我的错误中受益:)如果有人有什么要分享的,请分享。