Перетворення арифметичних виразів граматики


9

У статті Розбиття виразів за допомогою рекурсивного походження Теодора Норвелла (1999) автор починає з наступної граматики для арифметичних виразів:

E --> E "+" E | E "-" E | "-" E | E "*" E | E "/" E | E "^" E | "(" E ")" | v

що досить погано, тому що це неоднозначно і ліво-рекурсивно. Тож він починає з видалення лівої рекурсії від неї, і його результат такий:

E --> P {B P}
P --> v | "(" E ")" | U P
B --> "+" | "-" | "*" | "/" | "^"
U --> "-"

Але я не можу зрозуміти, як він дійшов до цього результату. Коли я намагаюся видалити ліву рекурсію самостійно, я роблю це наступним чином:

  1. Ялиці, я групую постановки, які не залишили рекурсії в одній групі, а інші (ліво-рекурсивні) в іншій групі:

    E --> E "+" E | E "-" E | E "*" E | E "/" E | E "^" E     // L-recursive
    E --> v | "(" E ")" | "-" E
  2. Далі я називаю їх і визначаю для легших маніпуляцій:

    E --> E B E  // L-recursive; B stands for "Binary operator"
    E --> P  // not L-recursive; P stands for "Primary Expression"
    P --> v | "(" E ")" | U E   // U stands for "Unary operator"
    B --> "+" | "-" | "*" | "/" | "^"
    P --> "-"

    Тепер мені потрібно розібратися лише з першими двома постановками, з якими зараз легше розібратися.

  3. Я переписую ці перші дві постановки, починаючи з не-L-рекурсивного виробництва (що просто P, первинний вираз) і слідуючи за ним за необов'язковим хвостом T, який я визначаю як решту початкового виробництва за винятком першого ліво-рекурсивного нетерміналу (тобто просто B E), за яким йде Хвіст T, або який може бути порожнім:

    E --> P T
    T --> B E T |

    (зверніть увагу на порожню альтернативу для хвоста).

  4. Ці дві постановки я зараз можу переписати у EBNF так:

    E --> P {B E}

    це майже те, що отримує автор, але я маю Eзамість Pнуля або більше повторення (Хвіст). Інші постановки я отримую зовсім так само, як і у нього:

    P --> v | "(" E ")" | U E
    B -> "+" | "-" | "*" | "/" | "^"
    U -> "-"

    але тут я маю Eзамість того, щоб Pу першому виробництві для P.

Отже, моє запитання: Що я пропускаю? Яке алгебраїчне перетворення в синтаксисі мені потрібно продовжити зараз, щоб отримати таку ж точну форму, як отримує автор? Я спробував заміни E, але це веде мене лише до циклів. Я підозрюю , що мені потрібно як - то замінити Pна E, але я не знаю , який - або правової трансформації , щоб виправдати його. Можливо, ви знаєте, що останній пропущений крок?


Подумайте про використання LaTeX для форматування. Ознайомтесь тут із грунтовкою . (Дивіться тут для обговорення придатності LaTeX у цьому випадку.)
Рафаель

Відповіді:


8

Відсутній крок:

E --> P T
T --> B E T |

переписати E в T:

E --> P T
T --> B P T T | 

Спростіть T:

E --> P T
T --> B P T | 

Дорівнює:

E --> P T
T --> {B P}

І ось ти.


1
Дякую за гарну відповідь :-) Тепер я бачу, що я пропустив: я замінив це навпаки, і в цьому була проблема. Але все одно я не розумію жодної деталі: звідки ти знаєш, що ти можеш спокійно з’єднати Ts разом в один T? Чи є для цього якесь правило? (Я підозрюю, що це може бути якось схоже на правило в булевій алгебраїчній логіці, яке говорить "aa = a".)
SasQ

До речі, чому цю посаду перенесли сюди з cstheory.sx і яка різниця? Я хотів би знати, щоб уникнути помилок у майбутньому.
SasQ

2
@SasQ CSTheory призначений лише для питань рівня дослідницької роботи в теоретичній інформатиці, детальніше див. FAQ щодо CSTheory.
Джухо

1
@SasQ: ТхТТε породжує х і так ТхТε. Більш загальне,LL=L для Lбудь-яку мову. Зауважте, що мати порожнє словоεоскільки права частина має вирішальне значення; це не стосується всіх граматичних фрагментів, якL+L+L+.
Рафаель

@Raphael: Це щось пов’язане з правилом ідентифікації *? Я побачив у «Книзі драконів» (3.3, с.91) це x** = x*. Це те саме правило, яке ви використовували?
SasQ
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.