annotate python/c3/lexer.py @ 148:e5263f74b287

Added c3 language frontend initial parser
author Windel Bouwman
date Fri, 01 Mar 2013 10:24:01 +0100
parents
children 74241ca312cc
rev   line source
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
1 import collections, re
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
2 from ppci.errors import CompilerException, SourceLocation
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
3
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
4 """
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
5 Lexical analyzer part. Splits the input character stream into tokens.
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
6 """
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
7
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
8 # Token is used in the lexical analyzer:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
9 Token = collections.namedtuple('Token', 'typ val loc')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
10
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
11 keywords = ['and', 'or', 'not','true', 'false', \
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
12 'else', 'if', 'while', 'return', \
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
13 'public', 'function', 'var', 'type', \
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
14 'import', 'package' ]
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
15
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
16 def tokenize(s):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
17 """
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
18 Tokenizer, generates an iterator that
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
19 returns tokens!
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
20
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
21 This GREAT example was taken from python re doc page!
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
22 """
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
23 tok_spec = [
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
24 ('REAL', r'\d+\.\d+'),
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
25 ('HEXNUMBER', r'0x[\da-fA-F]+'),
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
26 ('NUMBER', r'\d+'),
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
27 ('ID', r'[A-Za-z][A-Za-z\d_]*'),
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
28 ('NEWLINE', r'\n'),
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
29 ('SKIP', r'[ \t]'),
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
30 ('COMMENTS', r'//.*'),
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
31 ('LEESTEKEN', r'==|[\.,=:;\-+*\[\]/\(\)]|>=|<=|<>|>|<|{|}'),
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
32 ('STRING', r"'.*?'")
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
33 ]
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
34 tok_re = '|'.join('(?P<%s>%s)' % pair for pair in tok_spec)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
35 gettok = re.compile(tok_re).match
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
36 line = 1
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
37 pos = line_start = 0
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
38 mo = gettok(s)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
39 while mo is not None:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
40 typ = mo.lastgroup
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
41 val = mo.group(typ)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
42 if typ == 'NEWLINE':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
43 line_start = pos
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
44 line += 1
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
45 elif typ == 'COMMENTS':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
46 pass
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
47 elif typ == 'SKIP':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
48 pass
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
49 else:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
50 if typ == 'ID':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
51 if val in keywords:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
52 typ = val
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
53 elif typ == 'LEESTEKEN':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
54 typ = val
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
55 elif typ == 'NUMBER':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
56 val = int(val)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
57 elif typ == 'HEXNUMBER':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
58 val = int(val[2:], 16)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
59 typ = 'NUMBER'
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
60 elif typ == 'REAL':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
61 val = float(val)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
62 elif typ == 'STRING':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
63 val = val[1:-1]
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
64 loc = SourceLocation(line, mo.start()-line_start)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
65 yield Token(typ, val, loc)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
66 pos = mo.end()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
67 mo = gettok(s, pos)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
68 if pos != len(s):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
69 col = pos - line_start
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
70 pos = line
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
71 raise CompilerException('Unexpected character {0}'.format(s[pos]), pos)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
72 yield Token('END', '', line)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
73