As I explained in my answers tips for writing cfg, correct approach is first understand all possible patterns of strings in language then write rules.
What is this language L? In strings of language L:
1. All 'a'
s comes before any 'c'
s
2. Number of 'a'
are less than or equals to number of 'c'
, So in grammar of L, if a production rule adds one symbol 'a'
then it must also add one or more 'c'
.
3. There is no restriction on occurrence of symbol 'b'
, it can appear anywhere any number of times.
4. Empty (null) string is also belongs to L as number of 'a'
= number if 'c'
== 0. And for same reason a string consists of only symbol 'b'
is also acceptable.
5. Any string without 'a'
also belongs L (in other words (c + b)*
is subset of L).
Now writing grammar rules are easy (read comments to understand each production rules):
S → BaBSBCB | ^ // add `a` add `C` also, B can be any where so added B
Z → CZ | BZ | ^ // to create `(c + b)*`
C → cC | c // C always generates one or more `c`s
B → bB | ^ // there is no restriction on B it generates `b`s or ^