More doc updates

This commit is contained in:
David Beazley
2016-09-14 14:21:33 -05:00
parent 5c3083712f
commit 0a17f78d2e
5 changed files with 423 additions and 103 deletions

View File

@@ -8,14 +8,31 @@ sys.path.insert(0, "../..")
from sly import Lexer, Parser
class CalcLexer(Lexer):
tokens = (
'NAME', 'NUMBER',
)
ignore = ' \t'
literals = ['=', '+', '-', '*', '/', '(', ')']
# Set of token names. This is always required
tokens = {
'ID',
'NUMBER',
'PLUS',
'MINUS',
'TIMES',
'DIVIDE',
'ASSIGN',
'LPAREN',
'RPAREN',
}
# Tokens
NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'
# String containing ignored characters between tokens
ignore = ' \t'
# Regular expression rules for tokens
ID = r'[a-zA-Z_][a-zA-Z0-9_]*'
PLUS = r'\+'
MINUS = r'-'
TIMES = r'\*'
DIVIDE = r'/'
ASSIGN = r'='
LPAREN = r'\('
RPAREN = r'\)'
@_(r'\d+')
def NUMBER(self, t):
@@ -31,66 +48,50 @@ class CalcLexer(Lexer):
self.index += 1
class CalcParser(Parser):
# Get the token list from the lexer (required)
tokens = CalcLexer.tokens
precedence = (
('left', '+', '-'),
('left', '*', '/'),
('right', 'UMINUS'),
)
def __init__(self):
self.names = { }
# Grammar rules and actions
@_('expr PLUS term')
def expr(self, p):
return p.expr + p.term
@_('NAME "=" expression')
def statement(self, p):
self.names[p.NAME] = p.expression
@_('expr MINUS term')
def expr(self, p):
return p.expr - p.term
@_('expression')
def statement(self, p):
print(p.expression)
@_('term')
def expr(self, p):
return p.term
@_('expression "+" expression',
'expression "-" expression',
'expression "*" expression',
'expression "/" expression')
def expression(self, p):
if p[1] == '+':
return p.expression0 + p.expression1
elif p[1] == '-':
return p.expression0 - p.expression1
elif p[1] == '*':
return p.expression0 * p.expression1
elif p[1] == '/':
return p.expression0 / p.expression1
@_('term TIMES factor1')
def term(self, p):
return p.term * p.factor
@_('"-" expression %prec UMINUS')
def expression(self, p):
return -p.expression
@_('term DIVIDE factor')
def term(self, p):
return p.term / p.factor
@_('"(" expression ")"')
def expression(self, p):
return p.expression
@_('factor')
def term(self, p):
return p.factor
@_('NUMBER')
def expression(self, p):
def factor(self, p):
return p.NUMBER
@_('NAME')
def expression(self, p):
try:
return self.names[p.NAME]
except LookupError:
print("Undefined name '%s'" % p.NAME)
return 0
@_('LPAREN expr RPAREN')
def factor(self, p):
return p.expr
if __name__ == '__main__':
lexer = CalcLexer()
parser = CalcParser()
while True:
try:
text = input('calc > ')
result = parser.parse(lexer.tokenize(text))
print(result)
except EOFError:
break
if text:
parser.parse(lexer.tokenize(text))

98
example/calc_prec/calc.py Normal file
View File

@@ -0,0 +1,98 @@
# -----------------------------------------------------------------------------
# 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 "=" expr')
def statement(self, p):
self.names[p.NAME] = p.expr
@_('expr')
def statement(self, p):
print(p.expr)
@_('expr "+" expr')
def expr(self, p):
return p.expr0 + p.expr1
@_('expr "-" expr')
def expr(self, p):
return p.expr0 - p.expr1
@_('expr "*" expr')
def expr(self, p):
return p.expr0 * p.expr1
@_('expr "/" expr')
def expr(self, p):
return p.expr0 / p.expr1
@_('"-" expr %prec UMINUS')
def expr(self, p):
return -p.expr
@_('"(" expr ")"')
def expr(self, p):
return p.expr
@_('NUMBER')
def expr(self, p):
return p.NUMBER
@_('NAME')
def expr(self, p):
try:
return self.names[p.NAME]
except LookupError:
print("Undefined name '%s'" % p.NAME)
return 0
if __name__ == '__main__':
lexer = CalcLexer()
parser = CalcParser()
while True:
try:
text = input('calc > ')
except EOFError:
break
if text:
parser.parse(lexer.tokenize(text))