Example #1
0
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),
    ])
Example #2
0
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