LALR (1) пустой список параметров для функций - PullRequest
4 голосов
/ 16 января 2010

У меня есть простая грамматика LALR (1), но я столкнулся с проблемой.

start ::= spec.
spec ::= MOD STRING top_stmt.
spec ::= top_stmt.
top_stmt ::= stmt.
top_stmt ::= conditional.
stmt ::= expr.
stmt ::= assignment.
conditional ::= IF stmt_list.
expr ::= retval.
expr ::= NOT retval.
retval ::= access.
retval ::= invoke.
access ::= ns_identifier OBJECT_OPERATOR property_chain.
access ::= ns_identifier.
ns_identifier ::= identifier.
ns_identifier ::= ns_identifier NS_SEPARATOR identifier.
ns_identifier ::=.
property_chain ::= property_chain OBJECT_OPERATOR identifier.
property_chain ::= identifier.
identifier ::= VARIABLE.
identifier ::= STRING.
assignment ::= access ASSIGN expr. [ASSIGN]
stmt_list ::= stmt.
stmt_list ::= stmt_list COMMA stmt. [COMMA]
invoke ::= access LPAREN empty_stmt_list RPAREN.
empty_stmt_list ::=.
empty_stmt_list ::= stmt.
empty_stmt_list ::= empty_stmt_list COMMA stmt. [COMMA]

Точка обозначает конец правила, терминалам между скобками назначена ассоциативность: ASSIGN ассоциативно справа, COMMA ассоциативно слева.

Но лимон говорит, что не может уменьшить правило "empty_stmt_list :: =." потому что это не связано с начальным символом. Могу поспорить, что это: -)

Существует также конфликт синтаксического анализа для "invoke", он не может выбрать между RPAREN и COMMA, когда empty_stmt_list действительно является списком операторов empy.

Я пытаюсь проанализировать вызовы функций, которые не имеют (void) параметров.

Все остальное работает как положено.

Спасибо

Редактировать : я отредактировал свой оригинальный пост и опубликовал всю урезанную грамматику.

Ответы [ 2 ]

4 голосов
/ 17 января 2010

Ваша первая проблема в том, что я не думаю, что этот бит делает то, что вы хотите:

invoke ::= access LPAREN empty_stmt_list RPAREN.
empty_stmt_list ::=.
empty_stmt_list ::= stmt.
empty_stmt_list ::= empty_stmt_list COMMA stmt. [COMMA]

Производство invoke будет соответствовать access LPAREN COMMA stmt RPAREN, что, как я полагаю, нежелательно (и именно отсюда возникает конфликт LPAREN / COMMA).

Вы можете исправить это, выполнив это следующим образом, используя существующее правило stmt_list:

invoke ::= access LPAREN maybe_empty_stmt_list RPAREN.
maybe_empty_stmt_list ::= .
maybe_empty_stmt_list ::= stmt_list.

Это все еще сообщает о конфликте (но только 1 сейчас) и все еще жалуется, что maybe_empty_stmt_list ::=. не может быть уменьшено. Итак, заглянув в файл XXX.out, вы увидите, что это такое:

State 2:
...
     (16) ns_identifier ::= *
...
     (25) maybe_empty_stmt_list ::= *
...
                        RPAREN reduce 25  ** Parsing conflict **
....
                     {default} reduce 16

... похоже, проблема в правиле ns_identifier ::=.. Возвращаясь к описанным производственным процессам, нетрудно понять, что пустой ns_identifier можно уменьшить до stmt_list (через ns_identifier -> access -> retval -> expr -> * 1023. * -> stmt_list).

Это объясняет конфликт; и тот факт, что правило ns_identifier ::=. предпочтительнее в этом случае, потому что оно появляется раньше в грамматике (см. правила разрешения конфликтов уменьшения / уменьшения в документации , объясняет, почему оно жалуется, что правило maybe_empty_stmt_list ::=. никогда не уменьшайся.

0 голосов
/ 16 января 2010

Вы можете попробовать добавить правила приоритета для LPAREN / COMMA и проверить, влияет ли это на семантику в других местах.

...