class LenSubsScanner(MyScanner): """Following clapack, we remove ftnlen arguments, which f2c puts after a char * argument to hold the length of the passed string. This is just a nuisance in C. """ def __init__(self, info, name='<ftnlen>'): MyScanner.__init__(self, info, name) self.paren_count = 0 def beginArgs(self, text): if self.paren_count == 0: self.begin('args') self.paren_count += 1 return text def endArgs(self, text): self.paren_count -= 1 if self.paren_count == 0: self.begin('') return text digits = Re('[0-9]+') iofun = Re(r'\([^;]*;') decl = Re(r'\([^)]*\)[,;'+'\n]') any = Re('[.]*') S = Re('[ \t\n]*') cS = Str(',') + S len_ = Re('[a-z][a-z0-9]*_len') iofunctions = Str("s_cat", "s_copy", "s_stop", "s_cmp", "i_len", "do_fio", "do_lio") + iofun # Routines to not scrub the ftnlen argument from keep_ftnlen = (Str('ilaenv_') | Str('iparmq_') | Str('s_rnge')) + Str('(') lexicon = Lexicon([ (iofunctions, TEXT), (keep_ftnlen, beginArgs), State('args', [ (Str(')'), endArgs), (Str('('), beginArgs), (AnyChar, TEXT), ]), (cS+Re(r'[1-9][0-9]*L'), IGNORE), (cS+Str('ftnlen')+Opt(S+len_), IGNORE), (cS+sep_seq(['(', 'ftnlen', ')'], S)+S+digits, IGNORE), (Bol+Str('ftnlen ')+len_+Str(';\n'), IGNORE), (cS+len_, TEXT), (AnyChar, TEXT), ])
class DiceScanner(Scanner): digit1 = Range("19") digit = Str("0") | digit1 number = digit1 + Rep(digit) dice = NoCase(Any("dw")) plusminus = Any("+-") def scan_number(self, text): self.stack.append(int(text)) self.begin('gotnum') def scan_number2(self, text): # after a die, self.multiplier is set d = int(text) result = 0 self.produce('output', '(') for x in xrange(self.multiplier): number = random.randint(1, d) result += number self.produce('output', number) if x + 1 < self.multiplier: self.produce('output', '+') self.produce('output', ')') self.stack.append(result) # go back to default state self.begin('') def scan_dice(self, text): self.multiplier = 1 self.begin('afterdie') def scan_dice2(self, text): # stack has a multiplier on top self.multiplier = self.stack.pop() self.begin('afterdie') def scan_mod(self, text): self.stack.append(text) self.produce('output', text) self.begin('start') def scan_mod2(self, text): # calc after num: need to produce prev num self.produce('output', self.stack[-1]) self.scan_mod(text) def handle_endline(self, text): self.produce('output', self.stack[-1]) lexicon = Lexicon([ (dice, scan_dice), (number, scan_number), (plusminus, scan_mod), (Rep1(Any(" ")), IGNORE), State('start', [ (dice, scan_dice), (number, scan_number), (Rep1(Any(" ")), IGNORE), ]), State('gotnum', [ (dice, scan_dice2), (Rep1(Any(" ")), IGNORE), (plusminus, scan_mod2), (Eol, handle_endline), ]), State('afterdie', [ (number, scan_number2), (Rep1(Any(" ")), IGNORE), ]), ]) def __init__(self, f): Scanner.__init__(self, self.lexicon, f) self.stack = [] self.begin('start') self.result = 0