BNF Grammar для структур в стиле Python

Я пытаюсь использовать простую грамматику для анализа структур, подобных Python, это то, что я мог бы придумать для списка / набора

list : '[' atom ( ',' atom)* ']'
set : '(' atom ( ',' atom)* ']'

atom : 'a'..'z' | 'A'..'Z'
     | '[' list ']'
     | '(' set ')'

Обратите внимание, что это находится в antlr, я хотел знать о его правильности и любых ресурсах, которые могли бы мне помочь

Я посмотрел на грамматику python http://docs.python.org/reference/grammar.html, но не мог понять, что это обрабатывает список списков, или набор списков, или список наборов и т. д.

Любая помощь будет оценена.


person jack_carver    schedule 10.04.2012    source источник


Ответы (2)


не мог понять, что это был список списков, или набор списков, или список наборов и т. д.

Он не отличает списки от наборов или чего-то еще:

atom: ('(' [yield_expr|testlist_comp] ')' |
       '[' [listmaker] ']' |
       '{' [dictorsetmaker] '}' |
       '`' testlist1 '`' |
       NAME | NUMBER | STRING+)

То, как они обрабатывают рекурсию описываемого вами вида, состоит в том, что listmaker, dictorsetmaker и т. Д. В конечном итоге могут содержать atom. Например:

listmaker: test ( list_for | (',' test)* [','] )
test: or_test ['if' or_test 'else' test] | lambdef
or_test: and_test ('or' and_test)*
and_test: not_test ('and' not_test)*
not_test: 'not' not_test | comparison
comparison: expr (comp_op expr)*
expr: xor_expr ('|' xor_expr)*
xor_expr: and_expr ('^' and_expr)*
and_expr: shift_expr ('&' shift_expr)*
shift_expr: arith_expr (('<<'|'>>') arith_expr)*
arith_expr: term (('+'|'-') term)*
term: factor (('*'|'/'|'%'|'//') factor)*
factor: ('+'|'-'|'~') factor | power
power: atom trailer* ['**' factor]

Есть много промежуточных звеньев; это потому, что им нужно установить приоритет для набора математических операторов. Затем есть list_for, который позволяет добавлять дополнительные элементы для понимания списка.

Более упрощенный пример может выглядеть так:

atom: ('[' [list_or_set] ']' |
       '{' [list_or_set] '}' |
       NAME | NUMBER | STRING+)

list_or_set: atom (',' atom)* [',']

Или, если вы хотите, чтобы различие между списками и наборами проводилось на этом уровне:

atom: list | set | NAME | NUMBER | STRING+
list: '[' atom (',' atom)* [','] ']'
set: '{' atom (',' atom)* [','] '}'
person Karl Knechtel    schedule 10.04.2012
comment
Не различает - это неправильно; есть, конечно, отдельные listmaker и dictorsetmaker продукты, и синтаксический анализатор может полагаться на это при построении AST вместо того, чтобы повторно проверять скобки, чтобы выяснить, что в нем есть. - person Karl Knechtel; 10.04.2012

Это может быть ближе к тому, что вам нужно:

list : '[' element ( ',' element )* ']';
set : '(' element ( ',' element )* ')';

element: list | set | atom;

alpha:  'a'..'z' | 'A'..'Z' | '_' ;
alphanum: alpha | '0'..'9';
atom : alpha alphanum*;

Примечание: никогда раньше не использовал antlr, возможно, это неправильный синтаксис.

person Michael Slade    schedule 10.04.2012