# -*- coding: iso-8859-1 -*-

import sys
import actionrule, word, grammar
from topDownParser import TopDownParser

ParserClass, GrammarClass = TopDownParser, grammar.Grammar

try:
	from shiftReduceParser import ShiftReduceParser, ShiftReduceGrammar
	ParserClass, GrammarClass = ShiftReduceParser, ShiftReduceGrammar
except ImportError:
	pass


zahlwortGrammar = """=input
input -> "0" input
input -> zahl	

zahl -> mrd
zahl -> mio
zahl -> tsd
zahl -> hunderter
zahl -> zehner
zahl -> zifferLauteNull

mrd -> stelle vollemio	--- $1+" milliarden "+$2
mrd -> vollemrd
vollemrd -> hunderter vollemio	--- $1+" milliarden "+$2

mio -> stelle volletsd	--- $1+" millionen "+$2
mio -> vollemio
vollemio -> hunderter volletsd	--- $1+"millionen "+$2

tsd -> stelle hunderter	--- $1+"tausend"+$2
tsd -> volletsd
volletsd -> hunderter hunderter	--- $1+"tausend "+$2

stelle -> zehner
stelle -> ziffer

hunderter -> ziffer zehner	--- $1+"hundert"+$2
hunderter -> "0" zehner	--- $2

zehner -> "0" "0"	--- ""
zehner -> "0" letzteZiffer	--- $2
zehner -> "1" zehnZahl	--- $2
zehner -> zehnerZiffer "0"	--- $1
zehner -> zehnerZiffer zifferStilleNull	--- $2+"und"+$1

harmloseZiffer -> "2"	--- "zwei"
harmloseZiffer -> "3"	--- "drei"
harmloseZiffer -> "4"	--- "vier"
harmloseZiffer -> "5"	--- "fünf"
harmloseZiffer -> "6"	--- "sechs"
harmloseZiffer -> "7"	--- "sieben"
harmloseZiffer -> "8"	--- "acht"
harmloseZiffer -> "9"	--- "neun"

ziffer -> "1"	--- "ein"
ziffer -> harmloseZiffer

letzteZiffer -> "1"	--- "eins"
letzteZiffer -> harmloseZiffer

zifferLauteNull -> "0"	--- "null"
zifferLauteNull -> letzteZiffer

zifferStilleNull -> "0"	--- ""
zifferStilleNull -> ziffer

zehnZahl -> "0"	--- "zehn"
zehnZahl -> "1"	--- "elf"
zehnZahl -> "2"	--- "zwölf"
zehnZahl -> "3"	--- "dreizehn"
zehnZahl -> "4"	--- "vierzehn"
zehnZahl -> "5"	--- "fünfzehn"
zehnZahl -> "6"	--- "sechzehn"
zehnZahl -> "7"	--- "siebzehn"
zehnZahl -> "8"	--- "achtzehn"
zehnZahl -> "9"	--- "neunzehn"

zehnerZiffer -> "2"	--- "zwanzig"
zehnerZiffer -> "3"	--- "dreißig"
zehnerZiffer -> "4"	--- "vierzig"
zehnerZiffer -> "5"	--- "fünfzig"
zehnerZiffer -> "6"	--- "sechzig"
zehnerZiffer -> "7"	--- "siebzig"
zehnerZiffer -> "8"	--- "achtzig"
zehnerZiffer -> "9"	--- "neunzig"
"""

class Error(Exception):
	pass

def tokenizeChars(aString):
	"""turns the individual characters in a string into symbols
	digestable by word.Word's tokenizer.
	"""
	return " ".join(['"%s"'%c for c in aString])

class CfTransducer:
	"""This class encapsulates applying a parser to a Word (which 
	is a tokenized string of some sort) and running the actions
	associated with the rules found by the parser for the given
	word.
	"""
	def __init__(self, grammar, debug=False):
		self.debug = debug
		self.parser = ParserClass(grammar)
	
	def transduce(self, toParse):
		"""returns the value of the grammar's start symbol in a parse
		of toParse or raises an error if toParse doesn't parse.
		"""
		ruleSeq = self.parser.parse(toParse)
		if ruleSeq is None:
			raise Error("%s is not a valid input for this parser"%toParse)
		if self.debug:
			print ruleSeq
		return actionrule.runRuleSeq(ruleSeq)

if __name__=="__main__":
	gramm = GrammarClass(None, ruleString=zahlwortGrammar,
		ruleClass=actionrule.RuleWithAction)
	ng = CfTransducer(gramm)
	for inp in sys.argv[1:]:
		toParse = word.Word(tokenizeChars(str(int(inp))))
		print inp, ng.transduce(toParse)

