1# An implementation of Dartmouth BASIC (1964)
2
3from ply import *
4
5keywords = (
6    'LET', 'READ', 'DATA', 'PRINT', 'GOTO', 'IF', 'THEN', 'FOR', 'NEXT', 'TO', 'STEP',
7    'END', 'STOP', 'DEF', 'GOSUB', 'DIM', 'REM', 'RETURN', 'RUN', 'LIST', 'NEW',
8)
9
10tokens = keywords + (
11    'EQUALS', 'PLUS', 'MINUS', 'TIMES', 'DIVIDE', 'POWER',
12    'LPAREN', 'RPAREN', 'LT', 'LE', 'GT', 'GE', 'NE',
13    'COMMA', 'SEMI', 'INTEGER', 'FLOAT', 'STRING',
14    'ID', 'NEWLINE'
15)
16
17t_ignore = ' \t'
18
19
20def t_REM(t):
21    r'REM .*'
22    return t
23
24
25def t_ID(t):
26    r'[A-Z][A-Z0-9]*'
27    if t.value in keywords:
28        t.type = t.value
29    return t
30
31t_EQUALS = r'='
32t_PLUS = r'\+'
33t_MINUS = r'-'
34t_TIMES = r'\*'
35t_POWER = r'\^'
36t_DIVIDE = r'/'
37t_LPAREN = r'\('
38t_RPAREN = r'\)'
39t_LT = r'<'
40t_LE = r'<='
41t_GT = r'>'
42t_GE = r'>='
43t_NE = r'<>'
44t_COMMA = r'\,'
45t_SEMI = r';'
46t_INTEGER = r'\d+'
47t_FLOAT = r'((\d*\.\d+)(E[\+-]?\d+)?|([1-9]\d*E[\+-]?\d+))'
48t_STRING = r'\".*?\"'
49
50
51def t_NEWLINE(t):
52    r'\n'
53    t.lexer.lineno += 1
54    return t
55
56
57def t_error(t):
58    print("Illegal character %s" % t.value[0])
59    t.lexer.skip(1)
60
61lex.lex(debug=0)
62