Грамматика: разница между сверху вниз и снизу вверх? (Образец)

Это вопрос из грамматика: разница между сверху вниз и снизу вверх?

Я понимаю из этого вопроса, что:

  • сама грамматика не сверху-вниз или снизу-вверх, парсер
  • есть грамматики, которые могут быть проанализированы одним, но не другим
  • (спасибо Джерри Гроб

Итак, для этой грамматики (все возможные математические формулы):

    E -> E T E
    E -> (E)
    E -> D

    T -> + | - | * | /

    D -> 0
    D -> L G

    G -> G G    
    G -> 0 | L

    L -> 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 

будет ли это читаться парсером сверху вниз и снизу вверх?

могли бы вы сказать, что это грамматика сверху вниз или грамматика снизу вверх (или ни то, ни другое)?


Я спрашиваю, потому что у меня есть домашнее задание вопрос, который спрашивает:

"пишем сверху-вниз и снизу-вверх грамматики для языка, состоящего из всех ..."(вопрос)

Я не уверен, что это может быть правильно, так как кажется, что нет такой вещи, как грамматика сверху вниз и снизу вверх. Кто-нибудь может уточнить?

1 ответов


эта грамматика глупа, так как она объединяет лексику и синтаксический анализ как один. Но ладно, это академический пример.

вещь с дном-вверх и сверху вниз-это то, что имеет специальные угловые случаи, которые трудно реализовать с вами нормальный 1 взгляд вперед. Я, вероятно, думаю, что вы должны проверить, есть ли у него какие-либо проблемы и изменить грамматику.

чтобы понять вас грамматику, я написал правильный EBNF

expr:
    expr op expr |
    '(' expr ')' |
    number;

op:
    '+' |
    '-' |
    '*' |
    '/';

number:
    '0' |
    digit digits;

digits:
    '0' |
    digit |
    digits digits;

digit:
    '1' | 
    '2' | 
    '3' | 
    '4' | 
    '5' | 
    '6' | 
    '7' | 
    '8' | 
    '9'; 

мне особенно не нравится правило digits: digits digits. Это непонятно, где начинаются первые цифры и заканчиваются вторые. Я бы реализовал правило как

digits:
    '0' |
    digit |
    digits digit;

другая проблема number: '0' | digit digits; это противоречит digits: '0' и digits: digit;. На самом деле это дублируется. Я бы изменил правила на (удаление цифр):

number:
    '0' |
    digit |
    digit zero_digits;

zero_digits:
    zero_digit |
    zero_digits zero_digit;

zero_digit:
    '0' |
    digit;

это делает грамматику LR1 (левую рекурсивную с одним взглядом вперед) и контекст свободной. Это то, что вы обычно даете генератору парсера, такому как bison. И так как Зубр пьет до дна, это допустимый вход для парсера bottoms-up.

для подхода сверху вниз, по крайней мере для рекурсивного приличного, левый рекурсивный-это немного проблема. Вы можете использовать откат, если хотите, но для них вам нужна грамматика RR1(правая рекурсивная). Для этого замените рекурсии:

zero_digits:
    zero_digit |
    zero_digit zero_digits;

Я не уверен, что это ответ на ваш вопрос. Я думаю, что вопрос плохо сформулирован и вводит в заблуждение; и я пишу Парсеры на жизнь...