Prime numbers are often computed with very procedural, "artificial-looking" algorithms, such as consecutively checking divisors up to the square root, risking numbers in tables (sieves), and so on. Fibonacci numbers, on the other hands, can be "computed" from a very simple rewrite system:
axiom : A
rules : (A → AB), (B → A)
If you repeatedly apply the rules to the axiom, you get this sequence of strings:
n = 0 : A
n = 1 : AB
n = 2 : ABA
n = 3 : ABAAB
n = 4 : ABAABABA
n = 5 : ABAABABAABAAB
n = 6 : ABAABABAABAABABAABABA
n = 7 : ABAABABAABAABABAABABAABAABABAABAAB
And, if you count the length of each word, you get the sequence of Fibonacci numbers!
Are there are similarly simple ways to generate prime numbers?

According to wikipedia, the set of primes (represented as numerals in the usual fashion) can't be presented by a context-free grammar.
However, given the criterion on wikipedia, I'm nearly certain there is a context-sensitive grammar that gives primes.
In fact, I think I even have an idea of how to make a context-sensitive grammar whose production rules implement a sieve, although it's complicated enough that I'm not inclined to try to write it down.