gpt4 book ai didi

javascript - 递归 bool 值和/或数组 jison 解析器

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:28:30 25 4
gpt4 key购买 nike

我是 jison 的新手,并且设法拼凑出一个有用的查询解析器。我现在正在尝试创建一个解析器,它可以将像“a == 1 and b == 1 and c == 1”这样的字符串解析成像

这样的对象
{and: [
{a: {eq: 1}},
{b: {eq: 1}},
{c: {eq: 2}}
]}

而像“a == 1 或 b == 1 和 c == 1”这样的字符串应该解析成像这样的对象

{or: [
{a: {eq: 1}},
{and: [
{b: {eq: 1}},
{c: {eq: 1}}
]}
]}

到目前为止我的语法是这样的:

%lex

%%
\s+ /*skip whitespace*/
\"(\\.|[^"])*\" yytext = yytext.substr(1, yyleng-2); return 'STRING';
"==" return '==';
and[^\w] return 'and';
or[^\w] return 'or';
[0-9]+(?:\.[0-9]+)?\b return 'NUMBER';
[a-zA-Z][\.a-zA-Z0-9_]* return 'SYMBOL';
<<EOF>> return 'EOF';

/lex

%left 'or'
%left 'and'
%left '=='

%start expressions

%%

expressions
: e EOF
{$$ = $1;}
;

e
: property '==' value
{ $$ = {}; $[$1] = {eq: $3}; }
| boolAnd
{ $$ = {and: $1}}
| boolOr
{ $$ = {or: $1}}
;

boolAnd
: boolAnd 'and' e
{$$ = $1; $1.push($3);}
| e 'and' e
{$$ = [$1, $3];}
;

boolOr
: boolOr 'or' e
{$$ = $1; $1.push($3);}
| e 'or' e
{$$ = [$1, $3];}
;

property
: SYMBOL
{$$ = $1;}
;

value
: NUMBER
{$$ = Number(yytext);}
| STRING
{$$ = yytext; }
;

它给了我以下冲突错误:

Conflict in grammar: multiple actions possible when lookahead token is and in state 4
- reduce by rule: e -> boolAnd
- shift token (then go to state 11)
Conflict in grammar: multiple actions possible when lookahead token is or in state 5
- reduce by rule: e -> boolOr
- shift token (then go to state 12)

States with conflicts:
State 4
e -> boolAnd . #lookaheads= EOF and or
boolAnd -> boolAnd .and e #lookaheads= EOF and or
State 5
e -> boolOr . #lookaheads= EOF and or
boolOr -> boolOr .or e #lookaheads= EOF or and

有人能就我做错了什么提出建议吗?非常感谢

最佳答案

e : boolAnd

无法在以下两者之间做出决定:

boolAnd: e 'and' e
| boolAnd 'and' e

这就是 jison 所提示的。 (值得注意的是,将 boolAnd 简化为 e 似乎不是你想要的。这实际上是一个类型错误,或者如果 JS 有类型。)

就我个人而言,我只使用二叉树;根据我的经验,事实证明他们更容易合作。您可以使用单个非终结符和优先级声明轻松做到这一点。

%left 'or'
%left 'and'
%%
e
: property '==' value
{ $$ = {eq: [$1, $3]}; /* This seems better to me. YMMV. }
| e 'and' e
{ $$ = {and: [$1, $3]}}
| e 'or' e
{ $$ = {or: [$1, $3]}}
| '(' e ')'
{ $$ = $2 /* You didn't have this one, but it seems useful */ }
;

可以创建一个语法来处理可变运算符(即,将 x OP y OP z 减少为 {OP: [x, y, z]} ) 但要使其正确实际上需要大量工作,而且它不容易屈服于基于优先声明的解决方案。除非你真的想区分 x OP y OP zx OP (y OP z),这在 bool 运算符的情况下是不必要的,通常更容易和更一般的做法是在解析树的第二次遍历中折叠多个相似的二元运算符,或者在创建二元节点时直接通过检查子表达式的运算符类型来折叠多个相似的二元运算符。

关于javascript - 递归 bool 值和/或数组 jison 解析器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37082976/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com