We defined regular grammars by adding additional restrictions to the
definition of a context-free grammar. If we instead loosen restrictions,
we get what is called an Unrestricted Grammar
Unrestricted grammars aren’t used much in practice because they are
hard to work with (and no parsing algorithm exists). However, it is
interesting to know that they exist.
Definition
An Unrestricted Grammar is specified by a 4-tuple
(Σ,V,S,R), where
- Σ is an alphabet; the members of Σ are called
terminals.
- V is a (disjoint!) alphabet; the members of V
are called nonterminals.
- S∈V is called the start
symbol
- R is a set of rules of the form L→R where
L,R∈(Σ∪V)∗.
In other words, an unrestricted grammar is just like a context-free
grammar except the left-hand-side doesn’t have to be a single
nonterminal.
Example
The following grammar produces the (non-context-free!) language
{ anbncn ∣ n≥1 } :
SSbQccQ→→→→abcaSQbbccQc For example,
S⇒aSQ⇒aabcQ⇒aabQc⇒aabbcc. where we replaced cQ by
Qc in the third step and replaced
bQc by
bbcc in the fourth step.
We can read the rule
bQc→bbcc
as saying “we
can replace Q by bc, but only if that Q appears in-between b and
c.” In other words, whether we can replace Q by bc depends on
the context in which Q appears; the rule is
context-sensitive.
In contrast, the rule
Q→bc
lets us replace
Q by bc no matter where Q appears, i.e., no matter what context
Q appears in. Such rules are therefore called context-free,
and this is where the terminology of CFLs and CFGs comes from.
Example
Any language we can imagine computing can be described by some
unrestricted grammar. For example, the following grammar produces all
sequences of a’s whose length is composite (i.e., whose length is not
a prime number):
SCCTAZaZHZYAYaYUTaXAXHX→→→→→→→→→→→→→→HaCaCaTZUZAZAaHYAYaYTXXaaXaϵ