2014-01-24 4 views
0

Я хотел бы разобрать и f(arg).method, и f(arg) как block_statement; первый имеет более высокий приоритет, чем последний.Разбор двух видов заявлений с приоритетом

следующие элементы в parser.mly не может разобрать f(arg), но можно разобрать f(arg).method следующим образом:

(* f(arg).method *) 
    BS_MAE MAE_LE_UN (
    LE_IE IE_LE_AL (
     LE_SNE SNE_I f, 
     AL_I arg), 
    UN_I method) 

(* parser.mly: *)

block_statement: 
| member_access_expression { BS_MAE $1 } 

simple_name_expression: | IDENTIFIER { SNE_I $1 } 
member_access_expression: | l_expression DOT unrestricted_name { MAE_LE_UN ($1, $3) } 
unrestricted_name: | IDENTIFIER { UN_I $1 } 
index_expression: | l_expression LPAREN argument_list RPAREN { IE_LE_AL ($1, $3) } 
expression: | l_expression { E_LE $1 } 

l_expression: 
| simple_name_expression { LE_SNE $1 } 
| index_expression { LE_IE $1 } 

call_statement: 
| simple_name_expression argument_list { CallS_SNE_AL ($1, $2) } 
| member_access_expression argument_list { CallS_MAE_AL ($1, $2) } 

argument_list: | IDENTIFIER { AL_I $1 } 

Но если добавить еще одну строку | IDENTIFIER LPAREN expression RPAREN { BS_I_E ($1, $3) } для block_statement, на этот раз он может разобрать f(arg) следующим образом:

BS_I_E (
    f, 
    E_LE LE_SNE SNE_I arg) 

Однако на этот раз f(arg).method больше не может быть разобран. Он вызывает ошибку после прочтения .

Я не знаю, как дать парсеру пройти немного дальше, чтобы читать f(arg).method в целом, если это возможно; Мне действительно нужен парсер для анализа обоих заявлений ... Может ли кто-нибудь помочь?

ответ

1

Я хотел бы попробовать грамматику со структурой вдоль линий:

block: 
| expr 

expr: 
| expr LPAREN argument_list RPAREN 
| expr DOT unrestricted_name 
| simple_expr 

simple_expr: 
| IDENTIFIER 

Обратите внимание, что если вы хотите, чтобы разобрать полное предложение, а не только действительный префикс ввода, ваше правило верхнего уровня должен запросить лексема EOF присутствовать (чтобы заставить парсер идти до конца ввода):

%start <block> main 

main: 
| b=block EOF { b } 
+0

Спасибо: -) ... вы уверены, что 'F (Arg) .method' может быть хорошо проанализирован? '.method' должен быть прочитан как' DOT unrestricted_name', поэтому 'f (arg)' должен быть прочитан как 'member_access_expr', но это только другая ветвь' call_expr', которая содержит скобки ... – SoftTimur

+0

Действительно, я начал с чем-то, разбирающим ваш пример, внес изменения, и результирующая грамматика была неправильной. Я обновил его, чтобы объединить два уровня, чтобы разрешить разбор. Обратите внимание, что у вас должно быть правильное правило синтаксического анализа, которое идет до EOF (в противном случае вы можете получить префикс ввода, который является допустимым синтаксическим разбором), и что 'f (x) .y (z)' будет обрабатываться как '(f (x) .y) (z) ', как я и предполагал. – gasche

+0

Не могли бы вы подробнее рассказать о том, что вы должны иметь правильное правило синтаксического анализа, которое выходит за рамки EOF (иначе вы можете получить префикс ввода, который является действительным синтаксическим разбором)? Кроме того, я не вижу в вашей грамматике 'EOF' ... Я думаю, это ключ к решению моей проблемы: согласно моей грамматике' f (arg). Метод не может быть проанализирован, потому что 'f (arg) 'в качестве префикса является действительным parse ... – SoftTimur

Смежные вопросы