Использование Jison для преобразования списка команд в массив объектов
Я пытаюсь использовать Jison, который является JS-портом Bison, генератором парсера. Моя цель - преобразовать этот вход:
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 $1}
;
e
: FUNC_NAME OPEN_PAREN INTEGER CLOSE_PAREN
{$$ = { func: $1, arg: $3 };}
| FUNC_NAME OPEN_PAREN CLOSE_PAREN
{$$ = { func: $1 };}
;
Вывод полученного сгенерированного парсера { func: 'foo', arg: 10 }
, Другими словами, он возвращает только проанализированный объект из первого оператора и игнорирует остальные.
Я знаю, что моя проблема связана с семантической ценностью и "правой стороной" expression
, но я довольно потерян в противном случае.
Любая помощь будет чрезвычайно ценится!
1 ответ
Я добавляю грамматику, которая делает то, что вы просили. Существенные изменения:
LINE_END
имеет регулярное выражение\n+|$
также соответствовать концу вывода.Я добавил
start
производство, роль которого заключается только в том, чтобы вернуть конечный результат.Переписал
expression
производство для производства массивов. Я также удалил{return $1}
отe LINE_END
правило, так как это привело к преждевременному возвращению синтаксического анализатора.Модифицированный
expressions
производство для объединения массивов.
Для expression
а также expressions
там я использовал сокращенный синтаксис для правил. Например expression -> [$1]
эквивалентно expression { $$ = [$1] }
,
Вот грамматика:
%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 $1 }
;
expressions
: expressions expression -> $1.concat($2)
| expression
;
expression
: LINE_END -> []
| e LINE_END -> [$1]
;
e
: FUNC_NAME OPEN_PAREN INTEGER CLOSE_PAREN
{$$ = { func: $1, arg: $3 };}
| FUNC_NAME OPEN_PAREN CLOSE_PAREN
{$$ = { func: $1 };}
;
В сторону: Jison не порт Бизона. Это генератор парсеров, чье функционирование сильно вдохновлено Bison, но у него есть функции, которых у Bison нет, и есть некоторые функции Bison, которые Jison не поддерживает.