2020-05-07 12:26:57 +02:00
|
|
|
import ply.lex as lex
|
|
|
|
|
|
|
|
# Reserved values
|
|
|
|
reserved = {
|
2020-05-07 14:16:22 +02:00
|
|
|
'If': 'IF',
|
|
|
|
'Then': 'THEN',
|
|
|
|
'Else': 'ELSE',
|
|
|
|
'IfEnd': 'IFEND',
|
|
|
|
'While': 'WHILE',
|
|
|
|
'WhileEnd': 'WHILEEND',
|
|
|
|
'Do': 'DO',
|
|
|
|
'LpWhile': 'LPWHILE',
|
|
|
|
'For': 'FOR',
|
|
|
|
'To': 'TO',
|
|
|
|
'Step': 'STEP',
|
|
|
|
'Next': 'NEXT',
|
|
|
|
'Locate': 'LOCATE',
|
|
|
|
'Getkey': 'GETKEY',
|
|
|
|
'Not': 'NOT',
|
|
|
|
'And': 'And',
|
|
|
|
'Or': 'OR',
|
2020-05-08 10:48:22 +02:00
|
|
|
'List': 'LIST',
|
|
|
|
'Mat': 'MAT',
|
|
|
|
'Str': 'STR',
|
2020-05-08 11:29:52 +02:00
|
|
|
'Lbl': 'LBL',
|
|
|
|
'Goto': 'GOTO',
|
2020-05-07 12:26:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
# List of token names
|
|
|
|
tokens = [
|
2020-05-08 15:42:36 +02:00
|
|
|
'PLUS',
|
|
|
|
'MINUS',
|
|
|
|
'TIMES',
|
|
|
|
'DIVIDE',
|
|
|
|
'MODULO',
|
|
|
|
'LPAREN',
|
|
|
|
'RPAREN',
|
|
|
|
'LCURBRA',
|
|
|
|
'RCURBRA',
|
|
|
|
'LSQRBRA',
|
|
|
|
'RSQRBRA',
|
|
|
|
'ASSIGN',
|
|
|
|
'COMMA',
|
2020-05-07 12:26:57 +02:00
|
|
|
'STRING',
|
|
|
|
'NUMBER',
|
2020-05-08 10:44:32 +02:00
|
|
|
'ISEQUAL',
|
|
|
|
'PLUSASSIGN',
|
|
|
|
'MINUSASSIGN',
|
|
|
|
'TIMESASSIGN',
|
2020-05-08 15:42:36 +02:00
|
|
|
'DIVIDEASSIGN',
|
|
|
|
'MODULOASSIGN',
|
2020-05-07 12:26:57 +02:00
|
|
|
'NEWLINE',
|
|
|
|
'ID',
|
|
|
|
] + list(reserved.values())
|
|
|
|
|
|
|
|
# common regex
|
2020-05-08 15:42:36 +02:00
|
|
|
t_PLUS = r'\+'
|
|
|
|
t_MINUS = r'\-'
|
|
|
|
t_TIMES = r'\*'
|
|
|
|
t_DIVIDE = r'\/'
|
|
|
|
t_MODULO = r'\%'
|
|
|
|
t_LPAREN = r'\('
|
|
|
|
t_RPAREN = r'\)'
|
|
|
|
t_LCURBRA = r'\{'
|
|
|
|
t_RCURBRA = r'\}'
|
|
|
|
t_LSQRBRA = r'\['
|
|
|
|
t_RSQRBRA = r'\]'
|
|
|
|
t_ASSIGN = r'\='
|
|
|
|
t_COMMA = r'\,'
|
2020-05-08 10:44:32 +02:00
|
|
|
t_ISEQUAL = r'=='
|
|
|
|
t_PLUSASSIGN = r'\+='
|
|
|
|
t_MINUSASSIGN = r'\-='
|
|
|
|
t_TIMESASSIGN = r'\*='
|
2020-05-08 15:42:36 +02:00
|
|
|
t_DIVIDEASSIGN = r'/='
|
|
|
|
t_MODULOASSIGN = r'\%='
|
2020-05-07 12:26:57 +02:00
|
|
|
# Comments
|
2020-05-08 10:48:22 +02:00
|
|
|
t_ignore_COMMENT = r'//.*'
|
2020-05-07 12:26:57 +02:00
|
|
|
|
|
|
|
# A regex rule with some action code
|
|
|
|
def t_NUMBER(t):
|
2020-06-09 10:24:09 +02:00
|
|
|
r'[+-]*[(0-9).]+\b'
|
|
|
|
t.value = t.value.replace("+", "")
|
2020-06-09 10:36:34 +02:00
|
|
|
t.value = t.value.replace("--", "")
|
2020-06-09 10:24:09 +02:00
|
|
|
t.value = float(t.value)
|
2020-05-07 12:26:57 +02:00
|
|
|
return t
|
|
|
|
|
|
|
|
# Strings
|
|
|
|
def t_STRING(t):
|
|
|
|
'(\".*\")|(\'.*\')'
|
|
|
|
t.value = t.value[1:-1] # remove those thingies
|
|
|
|
t.value = t.value.replace('\\"', '"')
|
|
|
|
t.value = t.value.replace('"', '\\"')
|
|
|
|
return t
|
|
|
|
|
|
|
|
# Check for reserved words
|
|
|
|
def t_ID(t):
|
|
|
|
r'[a-zA-Z_][a-zA-Z_0-9]*'
|
|
|
|
t.type = reserved.get(t.value,'ID')
|
|
|
|
return t
|
|
|
|
|
|
|
|
# Define a rule so we can track line numbers
|
|
|
|
def t_newline(t):
|
|
|
|
r'(;|\n)+'
|
|
|
|
#r'\n+'
|
|
|
|
t.type = 'NEWLINE'
|
|
|
|
t.lexer.lineno += len(t.value)
|
|
|
|
return t
|
|
|
|
|
|
|
|
# A string containing ignored characters (spaces and tabs)
|
|
|
|
t_ignore = ' \t'
|
|
|
|
|
|
|
|
# Error handling rule
|
|
|
|
def t_error(t):
|
|
|
|
print("Illegal character '%s'" % t.value[0])
|
|
|
|
t.lexer.skip(1)
|
|
|
|
|
|
|
|
# Build the lex
|
|
|
|
lexer = lex.lex()
|