Советы по созданию "контекстно-свободной грамматики"

Я новичок в CFG,
Может кто-нибудь дать мне советы по созданию CFG, который генерирует некоторый язык

L = {am bn | m >= n}

что я получил:

So -> a | aSo | aS1 | e
S1 -> b | bS1 | e

но я думаю, что эта область неверна, потому что есть шанс, что число b'S может быть больше, чем as.

4 ответов


Как написать CFG с примером ambn

L = {am bn | m > = n}.

язык описание: am bn состоит из a следовал по b где количество a равны или больше, чем количество b.

пример строки: {^, a, aa, aab, aabb, aaaab, ab......}

так что всегда есть один a за один b но a возможны. заражать строку можно состоять из a только. Также обратите внимание ^ null является членом языка, потому что в ^ NumberOf(a) = NumberOf(b) = 0

Как написать грамматику, которая принимает язык, образованный строками am bn?

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

и это можно сделать примерно так:

   S --> aSb 

но это неполно, потому что нам нужно правило для генерации дополнительных as:

   A --> aA | a

объединить два производственных правила в одну грамматику CFG.

   S --> aSb | A
   A --> aA  | a

таким образом, вы можете генерировать любая строка, состоящая из a и a и b in (am bn) шаблон.

но в грамматике есть нет способ генерации ^ строку.

Итак, измените эту грамматику следующим образом:

   S --> B   | ^
   B --> aBb | A
   A --> aA  | a

эта грамматика может генерировать {am bn | m >= n} язык.

Примечание: для создания ^ нулевая строка, я добавил дополнительный первый шаг в грамматике, добавив S--> B | ^, так что вы можете либо добавить ^ или строку символов a и b. (теперь B играет роль S из предыдущей грамматики для генерации равных чисел a и b)

Edit: спасибо @Andy Хайден!--146--> Вы также можете написать эквивалентную грамматику для языка {аm bn / m >= n}:

   S --> aSb | A
   A --> aA | ^

обратите внимание: здесь A --> aA | ^ может генерировать ноль или любое количество a. И это должно быть предпочтительнее моей грамматики, потому что она генерирует меньшее дерево разбора для той же строки.
(меньше по высоте предпочтительнее из-за эффективного разбора)

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

  • вы должны быть ясны о языке, который он описывает (значение/шаблон).
  • вы можете вспомнить решения некоторых основных проблем(идея в том, что вы можете написать новый грамматик).
  • вы можете написать правила для основных языков, таких как я написал для RE в этом примере, чтобы написать Right-Linear-Grammmar. Правило поможет вам написать грамматику для новых языков.
  • один другой подход состоит в том, чтобы сначала нарисовать автоматы, затем преобразуйте автоматы в грамматику. У нас есть предопределенные методы написания грамматики из автоматов из любого класса формального языка.
  • как хороший программист, который учится, читая код других, точно так же можно научиться писать грамматики для формальных языков.

также грамматика, которую вы написали, неверна.


вы хотите создать грамматику для следующих языков

    L= {an bm | m>=n }

это означает, что число " b "должно быть больше или равно числу "a" или вы можете сказать, что для каждого " b "может быть не более одного "a". не наоборот.

вот грамматика для этого языка

      S-> aSb | Sb | b | ab

в этой грамматике для каждого " a "есть одно "b". но b может быть сгенерирован без генерации какого-либо "a".

вы также можете попробовать эти языки:

           L1= {an bm | m > n }
           L2= {an bm | m >= 2n }
           L3= {an bm | 2m >= n }
           L4= {an bm | m != n }

Я даю грамматику для каждого языка.

для L1

         S-> aSb | Sb | b

для L2

         S-> aSbb | Sb | abb

для L3

         S-> AASb | Sb | aab | ab | b

для L4

        S-> S1 | S2
        S1-> aS1b | S1b | b
        S2-> aS2b | aS2 | a

наименьшие переменные: S - > a S b | a S | e


с меньшим количеством переменных:

С -> а с б | з | б | е