annotate python/ks/lexer.py @ 192:6cd6260789a1

Added more tests for parser generator
author Windel Bouwman
date Sun, 26 May 2013 23:19:27 +0200
parents 4fd075e8259c
children
rev   line source
101
af0d7913677a Fixes and splitting into 3 stage
windel
parents: 98
diff changeset
1 import collections, re
1
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
2
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
3 """
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
4 Lexical analyzer part. Splits the input character stream into tokens.
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
5 """
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
6
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
7 # Token is used in the lexical analyzer:
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
8 Token = collections.namedtuple('Token', 'typ val row col')
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
9
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
10 keywords = ['and', 'array', 'begin', 'by', 'case', 'const', 'div', 'do', \
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
11 'else', 'elsif', 'end', 'false', 'for', 'if', 'import', 'in', 'is', \
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
12 'mod', 'module', 'nil', 'not', 'of', 'or', 'pointer', 'procedure', \
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
13 'record', 'repeat', 'return', 'then', 'to', 'true', 'type', 'until', 'var', \
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
14 'while', 'asm' ]
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
15
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
16 def tokenize(s):
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
17 """
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
18 Tokenizer, generates an iterator that
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
19 returns tokens!
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
20
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
21 This GREAT example was taken from python re doc page!
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
22 """
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
23 tok_spec = [
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
24 ('REAL', r'\d+\.\d+'),
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
25 ('HEXNUMBER', r'0x[\da-fA-F]+'),
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
26 ('NUMBER', r'\d+'),
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
27 ('ID', r'[A-Za-z][A-Za-z\d_]*'),
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
28 ('NEWLINE', r'\n'),
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
29 ('SKIP', r'[ \t]'),
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
30 ('COMMENTS', r'{.*}'),
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
31 ('LEESTEKEN', r':=|[\.,=:;\-+*\[\]/\(\)]|>=|<=|<>|>|<'),
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
32 ('STRING', r"'.*?'")
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
33 ]
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
34 tok_re = '|'.join('(?P<%s>%s)' % pair for pair in tok_spec)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
35 gettok = re.compile(tok_re).match
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
36 line = 1
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
37 pos = line_start = 0
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
38 mo = gettok(s)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
39 while mo is not None:
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
40 typ = mo.lastgroup
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
41 val = mo.group(typ)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
42 if typ == 'NEWLINE':
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
43 line_start = pos
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
44 line += 1
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
45 elif typ == 'COMMENTS':
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
46 pass
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
47 elif typ != 'SKIP':
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
48 if typ == 'ID':
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
49 if val in keywords:
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
50 typ = val
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
51 elif typ == 'LEESTEKEN':
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
52 typ = val
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
53 elif typ == 'NUMBER':
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
54 val = int(val)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
55 elif typ == 'HEXNUMBER':
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
56 val = int(val[2:], 16)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
57 typ = 'NUMBER'
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
58 elif typ == 'REAL':
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
59 val = float(val)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
60 elif typ == 'STRING':
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
61 val = val[1:-1]
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
62 yield Token(typ, val, line, mo.start()-line_start)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
63 pos = mo.end()
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
64 mo = gettok(s, pos)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
65 if pos != len(s):
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
66 col = pos - line_start
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
67 raise CompilerException('Unexpected character {0}'.format(s[pos]), line, col)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
68 yield Token('END', '', line, 0)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
69