A resposta para o seu exemplo específico está lá, mas a pergunta geral permanece.
Em muitos anos, tanto na ciência da computação teórica quanto na aplicada, não me lembro de ter que escrever uma gramática de CS como tal.
Ainda assim, se eu posso dar um conselho, isso não deve ser visto como produzir uma gramática de CF, se você tiver que inventar as regras para colocar tudo no lugar e coordenar exatamente como é produzido.
As gramáticas de CS são muito mais algorítmicas e você pode imitar uma máquina de Turing (trabalhando em espaço finito, proporcional ao tamanho da entrada, o que significa LBA) para mover as coisas conforme necessário. Portanto, é muito mais um exercício de programação.
Você pode praticamente gerar os primeiros ingredientes para criar uma das palavras no idioma e movê-las algoritmicamente. Você pode usar símbolos especiais (possivelmente em vários sabores correspondentes ao estado finito) para agir como cabeças que você move com as regras apropriadas, para verificar o que deve ser feito. E assim por diante.
Uma boa leitura pode ser procurar a prova de equivalência entre os idiomas CSG e os idiomas LBA, ou seja, os idiomas CS.
Lembre-se de que quase todos os algoritmos com os quais trabalhamos podem ser executados por um LBA, portanto, correspondem a uma linguagem definível por CSG. Isso deve lhe dar uma idéia do poder algorítmico disponível.
Mas um pouco de imaginação ajuda a soluções elegantes, como no exemplo que você deu.