sly/example/calc/calc.py

98 lines
2.1 KiB
Python
Raw Normal View History

2016-09-02 21:07:32 +02:00
# -----------------------------------------------------------------------------
# calc.py
# -----------------------------------------------------------------------------
import sys
sys.path.insert(0, "../..")
from sly import Lexer, Parser
class CalcLexer(Lexer):
tokens = (
'NAME', 'NUMBER',
)
ignore = ' \t'
literals = ['=', '+', '-', '*', '/', '(', ')']
# Tokens
NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'
@_(r'\d+')
def NUMBER(self, t):
t.value = int(t.value)
return t
@_(r'\n+')
def newline(self, t):
self.lineno += t.value.count('\n')
def error(self, value):
print("Illegal character '%s'" % value[0])
self.index += 1
class CalcParser(Parser):
tokens = CalcLexer.tokens
precedence = (
('left', '+', '-'),
('left', '*', '/'),
('right', 'UMINUS'),
)
def __init__(self):
self.names = { }
@_('NAME "=" expression')
def statement(self, p):
2016-09-02 21:07:32 +02:00
self.names[p[1]] = p[3]
@_('expression')
def statement(self, p):
2016-09-02 21:07:32 +02:00
print(p[1])
@_('expression "+" expression',
'expression "-" expression',
'expression "*" expression',
'expression "/" expression')
def expression(self, p):
2016-09-02 21:07:32 +02:00
if p[2] == '+':
p[0] = p[1] + p[3]
elif p[2] == '-':
p[0] = p[1] - p[3]
elif p[2] == '*':
p[0] = p[1] * p[3]
elif p[2] == '/':
p[0] = p[1] / p[3]
@_('"-" expression %prec UMINUS')
def expression(self, p):
2016-09-02 21:07:32 +02:00
p[0] = -p[2]
@_('"(" expression ")"')
def expression(self, p):
2016-09-02 21:07:32 +02:00
p[0] = p[2]
@_('NUMBER')
def expression(self, p):
2016-09-02 21:07:32 +02:00
p[0] = p[1]
@_('NAME')
def expression(self, p):
2016-09-02 21:07:32 +02:00
try:
p[0] = self.names[p[1]]
except LookupError:
print("Undefined name '%s'" % p[1])
p[0] = 0
if __name__ == '__main__':
lexer = CalcLexer()
2016-09-02 21:07:32 +02:00
parser = CalcParser()
while True:
try:
text = input('calc > ')
2016-09-02 21:07:32 +02:00
except EOFError:
break
if text:
parser.parse(lexer.tokenize(text))