使用 Jison 将命令列表转换为对象数组
Using Jison to convert a list of commands into an array of objects
我正在尝试使用 Jison,它是解析器生成器 Bison 的 JS 端口。我的目标是转换此输入:
foo(10)
bar()
foo(28)
baz(28)
进入这个:
[
{ func: 'foo', arg: 10 },
{ func: 'bar' },
{ func: 'foo', arg: 28 },
{ func: 'baz', arg: 28 }
]
这是我的野牛文件:
%lex
%%
[0-9]+\b return 'INTEGER'
\( return 'OPEN_PAREN'
\) return 'CLOSE_PAREN'
[\w]+\s*(?=\() return 'FUNC_NAME'
\n+ return 'LINE_END'
/lex
%%
expressions
: expressions expression
| expression
;
expression
: LINE_END
| e LINE_END
{return }
;
e
: FUNC_NAME OPEN_PAREN INTEGER CLOSE_PAREN
{$$ = { func: , arg: };}
| FUNC_NAME OPEN_PAREN CLOSE_PAREN
{$$ = { func: };}
;
生成的解析器的输出是 { func: 'foo', arg: 10 }
。换句话说,它只 returns 第一个语句中的已解析对象而忽略其余部分。
我知道我的问题与语义值和 expression
的 "right side" 有关,但除此之外我很迷茫。
任何帮助将不胜感激!
我正在附加一个语法来满足您的要求。显着变化是:
LINE_END
有正则表达式 \n+|$
也匹配输出的结尾。
我添加了一个start
制作,它的作用只是return最终结果。
重写了 expression
产生式以产生数组。我还从 e LINE_END
规则中删除了 {return }
,因为这会导致解析器过早地 return。
修改了 expressions
产生式以连接数组。
对于 expression
和 expressions
作品,我在那里的规则使用了 shorthand 语法。例如 expression -> []
等同于 expression { $$ = [] }
.
语法如下:
%lex
%%
[0-9]+\b return 'INTEGER'
\( return 'OPEN_PAREN'
\) return 'CLOSE_PAREN'
[\w]+\s*(?=\() return 'FUNC_NAME'
\n+|$ return 'LINE_END'
/lex
%%
start:
expressions
{ return }
;
expressions
: expressions expression -> .concat()
| expression
;
expression
: LINE_END -> []
| e LINE_END -> []
;
e
: FUNC_NAME OPEN_PAREN INTEGER CLOSE_PAREN
{$$ = { func: , arg: };}
| FUNC_NAME OPEN_PAREN CLOSE_PAREN
{$$ = { func: };}
;
旁白:Jison 不是 Bison 的港口。它是一个解析器生成器,其功能受到 Bison 的强烈启发,但它具有 Bison 没有的功能,并且 Jison 不支持 Bison 的某些功能。
我正在尝试使用 Jison,它是解析器生成器 Bison 的 JS 端口。我的目标是转换此输入:
foo(10)
bar()
foo(28)
baz(28)
进入这个:
[
{ func: 'foo', arg: 10 },
{ func: 'bar' },
{ func: 'foo', arg: 28 },
{ func: 'baz', arg: 28 }
]
这是我的野牛文件:
%lex
%%
[0-9]+\b return 'INTEGER'
\( return 'OPEN_PAREN'
\) return 'CLOSE_PAREN'
[\w]+\s*(?=\() return 'FUNC_NAME'
\n+ return 'LINE_END'
/lex
%%
expressions
: expressions expression
| expression
;
expression
: LINE_END
| e LINE_END
{return }
;
e
: FUNC_NAME OPEN_PAREN INTEGER CLOSE_PAREN
{$$ = { func: , arg: };}
| FUNC_NAME OPEN_PAREN CLOSE_PAREN
{$$ = { func: };}
;
生成的解析器的输出是 { func: 'foo', arg: 10 }
。换句话说,它只 returns 第一个语句中的已解析对象而忽略其余部分。
我知道我的问题与语义值和 expression
的 "right side" 有关,但除此之外我很迷茫。
任何帮助将不胜感激!
我正在附加一个语法来满足您的要求。显着变化是:
LINE_END
有正则表达式\n+|$
也匹配输出的结尾。我添加了一个
start
制作,它的作用只是return最终结果。重写了
expression
产生式以产生数组。我还从e LINE_END
规则中删除了{return }
,因为这会导致解析器过早地 return。修改了
expressions
产生式以连接数组。
对于 expression
和 expressions
作品,我在那里的规则使用了 shorthand 语法。例如 expression -> []
等同于 expression { $$ = [] }
.
语法如下:
%lex
%%
[0-9]+\b return 'INTEGER'
\( return 'OPEN_PAREN'
\) return 'CLOSE_PAREN'
[\w]+\s*(?=\() return 'FUNC_NAME'
\n+|$ return 'LINE_END'
/lex
%%
start:
expressions
{ return }
;
expressions
: expressions expression -> .concat()
| expression
;
expression
: LINE_END -> []
| e LINE_END -> []
;
e
: FUNC_NAME OPEN_PAREN INTEGER CLOSE_PAREN
{$$ = { func: , arg: };}
| FUNC_NAME OPEN_PAREN CLOSE_PAREN
{$$ = { func: };}
;
旁白:Jison 不是 Bison 的港口。它是一个解析器生成器,其功能受到 Bison 的强烈启发,但它具有 Bison 没有的功能,并且 Jison 不支持 Bison 的某些功能。