# An implementation of Dartmouth BASIC (1964) from ply import * keywords = ( 'LET', 'READ', 'DATA', 'PRINT', 'GOTO', 'IF', 'THEN', 'FOR', 'NEXT', 'TO', 'STEP', 'END', 'STOP', 'DEF', 'GOSUB', 'DIM', 'REM', 'RETURN', 'RUN', 'LIST', 'NEW', ) tokens = keywords + ( 'EQUALS', 'PLUS', 'MINUS', 'TIMES', 'DIVIDE', 'POWER', 'LPAREN', 'RPAREN', 'LT', 'LE', 'GT', 'GE', 'NE', 'COMMA', 'SEMI', 'INTEGER', 'FLOAT', 'STRING', 'ID', 'NEWLINE' ) t_ignore = ' \t' def t_REM(t): r'REM .*' return t def t_ID(t): r'[A-Z][A-Z0-9]*' if t.value in keywords: t.type = t.value return t t_EQUALS = r'=' t_PLUS = r'\+' t_MINUS = r'-' t_TIMES = r'\*' t_POWER = r'\^' t_DIVIDE = r'/' t_LPAREN = r'\(' t_RPAREN = r'\)' t_LT = r'<' t_LE = r'<=' t_GT = r'>' t_GE = r'>=' t_NE = r'<>' t_COMMA = r'\,' t_SEMI = r';' t_INTEGER = r'\d+' t_FLOAT = r'((\d*\.\d+)(E[\+-]?\d+)?|([1-9]\d*E[\+-]?\d+))' t_STRING = r'\".*?\"' def t_NEWLINE(t): r'\n' t.lexer.lineno += 1 return t def t_error(t): print("Illegal character %s" % t.value[0]) t.lexer.skip(1) lex.lex(debug=0)