Track line numbers in AST nodes.

pull/15/head
Jussi Pakkanen 12 years ago
parent cfad3eb371
commit 6cfd7d65d9
  1. 46
      nodes.py
  2. 19
      parser.py

@ -15,7 +15,11 @@
# limitations under the License.
class Node():
pass
def __init__(self, lineno):
self.line_number = lineno
def lineno(self):
return self.line_number
class Expression(Node):
pass
@ -24,30 +28,30 @@ class Statement(Node):
pass
class AtomExpression(Expression):
def __init__(self, value):
Expression.__init__(self)
def __init__(self, value, lineno):
Expression.__init__(self, lineno)
self.value = value
class StringExpression(Expression):
def __init__(self, value):
Expression.__init__(self)
def __init__(self, value, lineno):
Expression.__init__(self, lineno)
self.value = value
class AtomStatement(Statement):
def __init__(self, value):
Statement.__init__(self)
def __init__(self, value, lineno):
Statement.__init__(self, lineno)
assert(type(value) == type(''))
self.value = value
class StringStatement(Statement):
def __init__(self, value):
def __init__(self, value, lineno):
assert(type(value) == type(''))
Statement.__init__(self)
Statement.__init__(self, lineno)
self.value = value
class FunctionCall(Statement):
def __init__(self, func_name, arguments):
Statement.__init__(self)
def __init__(self, func_name, arguments, lineno):
Statement.__init__(self, lineno)
self.func_name = func_name
self.arguments = arguments
@ -55,21 +59,21 @@ class FunctionCall(Statement):
return self.func_name.value
class MethodCall(Statement):
def __init__(self, object_name, method_name, arguments):
Statement.__init__(self)
def __init__(self, object_name, method_name, arguments, lineno):
Statement.__init__(self, lineno)
self.object_name = object_name
self.method_name = method_name
self.arguments = arguments
class Assignment(Statement):
def __init__(self, var_name, value):
Statement.__init__(self)
def __init__(self, var_name, value, lineno):
Statement.__init__(self, lineno)
self.var_name = var_name
self.value = value
class CodeBlock(Statement):
def __init__(self):
Statement.__init__(self)
def __init__(self, lineno):
Statement.__init__(self, lineno)
self.statements = []
def prepend(self, statement):
@ -79,8 +83,8 @@ class CodeBlock(Statement):
return self.statements
class Arguments(Statement):
def __init__(self):
Statement.__init__(self)
def __init__(self, lineno):
Statement.__init__(self, lineno)
self.arguments = []
def prepend(self, statement):
@ -88,7 +92,7 @@ class Arguments(Statement):
def statement_from_expression(expr):
if isinstance(expr, AtomExpression):
return AtomStatement(expr.value)
return AtomStatement(expr.value, expr.lineno())
if isinstance(expr, StringExpression):
return StringStatement(expr.value)
return StringStatement(expr.value, expr.lineno())
raise RuntimeError('Can not convert unknown expression to a statement.')

@ -76,29 +76,29 @@ def p_codeblock(t):
def p_codeblock_last(t):
'codeblock : statement EOL'
cb = nodes.CodeBlock()
cb = nodes.CodeBlock(t.lineno(1))
cb.prepend(t[1])
t[0] = cb
def p_expression_atom(t):
'expression : ATOM'
t[0] = nodes.AtomExpression(t[1])
t[0] = nodes.AtomExpression(t[1], t.lineno(1))
def p_expression_string(t):
'expression : STRING'
t[0] = nodes.StringExpression(t[1])
t[0] = nodes.StringExpression(t[1], t.lineno(1))
def p_statement_assign(t):
'statement : expression EQUALS statement'
t[0] = nodes.Assignment(t[1], t[3])
t[0] = nodes.Assignment(t[1], t[3], t.lineno(1))
def p_statement_func_call(t):
'statement : expression LPAREN args RPAREN'
t[0] = nodes.FunctionCall(t[1], t[3])
t[0] = nodes.FunctionCall(t[1], t[3], t.lineno(1))
def p_statement_method_call(t):
'statement : expression DOT expression LPAREN args RPAREN'
t[0] = nodes.MethodCall(t[1], t[3], t[5])
t[0] = nodes.MethodCall(t[1], t[3], t[5], t.lineno(1))
def p_statement_expression(t):
'statement : expression'
@ -112,13 +112,13 @@ def p_args_multiple(t):
def p_args_single(t):
'args : statement'
args = nodes.Arguments()
args = nodes.Arguments(t.lineno(1))
args.prepend(t[1])
t[0] = args
def p_args_none(t):
'args :'
t[0] = nodes.Arguments()
t[0] = nodes.Arguments(t.lineno(0))
def p_error(t):
print('Parser errored out at: ' + t.value)
@ -141,8 +141,7 @@ def test_lexer():
def test_parser():
code = """func_call('something', 'or else')
objectname.methodname(abc)
emptycall()
"""
emptycall()"""
print(build_ast(code))
def build_ast(code):

Loading…
Cancel
Save