Created
March 26, 2012 17:30
-
-
Save ikeikeikeike/2207007 to your computer and use it in GitHub Desktop.
parser.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
import sys | |
import ply.yacc as yacc | |
from lexer import AssignLexer | |
import core | |
_quiet = True | |
class AssignLogger(yacc.PlyLogger): | |
def debug(self, *args, **kwargs): | |
if not _quiet: | |
super(type(self), self).debug(*args, **kwargs) | |
class AssignParser(object): | |
tokens = AssignLexer.tokens | |
def __init__(self, **yacc_args): | |
self.lexer = None | |
self.yacc_args = yacc_args | |
def parse(self, source_text, debug=0): | |
if self.lexer is None: | |
self.lexer = AssignLexer() | |
self.parser = yacc.yacc(module=self, | |
errorlog=AssignLogger(sys.stderr), **self.yacc_args) | |
return self.parser.parse(source_text, lexer=self.lexer, debug=debug) | |
def p_error(self, p): | |
if hasattr(p.lexer, "lexdata"): | |
source = p.lexer.lexdata | |
begin = source.rfind('\n', 0, p.lexpos) | |
end = source.find('\n', p.lexpos) | |
line = source[begin + 1:end] | |
print('Syntax error in input: row=%d col=%d\nerror => %s' | |
% (p.lineno, p.lexpos - begin, line)) | |
else: | |
print('Syntax error in input') | |
def Assign(self, left, right): | |
if isinstance(left, core.Name): | |
return core.Assign([core.AssName(left.name, 'OP_ASSIGN')], right) | |
else: | |
raise SyntaxError("Can't do that yet") | |
def p_expr_stmt(self, p): | |
"""expr_stmt : testlist ASSIGN testlist | |
| testlist """ | |
if len(p) == 2: | |
# a list of expressions | |
p[0] = core.Discard(p[1]) | |
else: | |
p[0] = self.Assign(p[1], p[3]) | |
def p_atom_name(self, p): | |
"""atom : NAME""" | |
p[0] = core.Name(p[1]) | |
def p_atom_number(self, p): | |
"""atom : NUMBER""" | |
p[0] = core.Const(p[1]) | |
def p_atom_string(self, p): | |
"""atom : STRING""" | |
p[0] = core.Const(p[1]) | |
def p_testlist(self, p): | |
"""testlist : testlist_multi""" | |
if len(p) == 2: | |
p[0] = p[1] | |
else: | |
if isinstance(p[1], list): | |
p[0] = p[1] | |
else: | |
p[0] = [p[1]] | |
if isinstance(p[0], list): | |
raise AssertionError("not implemented") | |
def p_testlist_multi(self, p): | |
"""testlist_multi : test""" | |
if len(p) == 2: | |
# singleton | |
p[0] = p[1] | |
else: | |
if isinstance(p[1], list): | |
p[0] = p[1] + [p[3]] | |
else: | |
raise AssertionError("not implemented") | |
def p_test(self, p): | |
"""test : comparison""" | |
p[0] = p[1] | |
_binary_ops = { | |
"+": core.Add, | |
"-": core.Sub, | |
"*": core.Mul, | |
"/": core.Div, | |
} | |
_unary_ops = { | |
"+": core.UnaryAdd, | |
"-": core.UnarySub, | |
} | |
def p_comparison(self, p): | |
"""comparison : comparison PLUS comparison | |
| comparison MINUS comparison | |
| comparison MULT comparison | |
| comparison DIV comparison | |
| PLUS comparison | |
| MINUS comparison | |
| power""" | |
if len(p) == 4: | |
p[0] = self._binary_ops[p[2]]((p[1], p[3])) | |
elif len(p) == 3: | |
p[0] = self._unary_ops[p[1]](p[2]) | |
else: | |
p[0] = p[1] | |
def p_power(self, p): | |
"""power : atom""" | |
if len(p) == 2: | |
p[0] = p[1] | |
else: | |
raise AssertionError("not implemented") | |
if __name__ == '__main__': | |
import pprint | |
# enable AssignLogger | |
_quiet = False | |
source_text = """ | |
'test' | |
""" | |
syntax_tree = AssignParser().parse(source_text, debug=0) | |
pprint.pprint(syntax_tree) | |
print("----------") | |
source_text = """ | |
1 * 2 - 1 / 3 | |
""" | |
syntax_tree = AssignParser().parse(source_text, debug=0) | |
pprint.pprint(syntax_tree) | |
print("----------") | |
source_text = """ | |
name = 1 + 2 + 10 | |
""" | |
syntax_tree = AssignParser().parse(source_text, debug=0) | |
pprint.pprint(syntax_tree) | |
print("----------") | |
source_text = """ | |
name = "name" | |
""" | |
syntax_tree = AssignParser().parse(source_text, debug=0) | |
pprint.pprint(syntax_tree) | |
print("----------") | |
source_text = """ | |
name = "(`Д´)ノ" | |
""" | |
syntax_tree = AssignParser().parse(source_text, debug=0) | |
pprint.pprint(syntax_tree) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment