Skip to content

Instantly share code, notes, and snippets.

@tmhedberg
Created November 12, 2012 22:17
Show Gist options
  • Select an option

  • Save tmhedberg/4062363 to your computer and use it in GitHub Desktop.

Select an option

Save tmhedberg/4062363 to your computer and use it in GitHub Desktop.
Procedurally generated quasi-poetry
POEM: <LINE> <LINE> <LINE> <LINE> <LINE>
LINE: <NOUN>|<PREPOSITION>|<PRONOUN> $LINEBREAK
ADJECTIVE: black|white|dark|light|bright|murky|muddy|clear <NOUN>|<ADJECTIVE>|$END
NOUN: heart|sun|moon|thunder|fire|time|wind|sea|river|flavor|wave|willow|rain|tree|flower|field|meadow|pasture|harvest|water|father|mother|brother|sister <VERB>|<PREPOSITION>|$END
PRONOUN: my|your|his|her <NOUN>|<ADJECTIVE>
VERB: runs|walks|stands|climbs|crawls|flows|flies|transcends|ascends|descends|sinks <PREPOSITION>|<PRONOUN>|$END
PREPOSITION: above|across|against|along|among|around|before|behind|beneath|beside|between|beyond|during|inside|onto|outside|under|underneath|upon|with|without|through <NOUN>|<PRONOUN>|<ADJECTIVE>
#!/usr/bin/ruby
unless ARGV[0]
$stderr.puts 'No input grammar specified'
exit 1
end
unless File.readable? ARGV[0]
$stderr.puts 'Specified grammar file does not exist or cannot be read'
exit 2
end
@productions = {}
File.new(ARGV[0]).each_with_index do |rule, i|
name, body = rule.split /:\s*/, 2
ROOT_PRODUCTION = name if i == 0
@productions[name] = body.split(/\s+/).map { |opts| opts.split '|' }
end
def satisfy(production)
@productions[production].each { |opts| handle_opt opts.sample }
end
def handle_opt(opt)
case opt
when /^<([A-Z]+)>$/
satisfy $~[1]
when '$LINEBREAK'
puts
when '$END'
return
else
print "#{opt} "
end
end
satisfy ROOT_PRODUCTION
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment