aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/mparser.py
diff options
context:
space:
mode:
Diffstat (limited to 'mesonbuild/mparser.py')
-rw-r--r--mesonbuild/mparser.py127
1 files changed, 75 insertions, 52 deletions
diff --git a/mesonbuild/mparser.py b/mesonbuild/mparser.py
index f593c8e..ad1fedd 100644
--- a/mesonbuild/mparser.py
+++ b/mesonbuild/mparser.py
@@ -22,10 +22,12 @@ class ParseException(MesonException):
self.colno = colno
class Token:
- def __init__(self, tid, lineno, colno, value):
+ def __init__(self, tid, subdir, lineno, colno, bytespan, value):
self.tid = tid
+ self.subdir = subdir
self.lineno = lineno
self.colno = colno
+ self.bytespan = bytespan
self.value = value
def __eq__(self, other):
@@ -71,7 +73,7 @@ class Lexer:
('questionmark', re.compile(r'\?')),
]
- def lex(self, code):
+ def lex(self, code, subdir):
lineno = 1
line_start = 0
loc = 0;
@@ -87,7 +89,10 @@ class Lexer:
curline = lineno
col = mo.start()-line_start
matched = True
+ span_start = loc
loc = mo.end()
+ span_end = loc
+ bytespan = (span_start, span_end)
match_text = mo.group()
if tid == 'ignore' or tid == 'comment':
break
@@ -123,40 +128,41 @@ class Lexer:
tid = match_text
else:
value = match_text
- yield Token(tid, curline, col, value)
+ yield Token(tid, subdir, curline, col, bytespan, value)
break
if not matched:
raise ParseException('lexer', lineno, col)
-class BooleanNode:
- def __init__(self, token, value):
+class ElementaryNode:
+ def __init__(self, token):
self.lineno = token.lineno
+ self.subdir = token.subdir
self.colno = token.colno
+ self.value = token.value
+ self.bytespan = token.bytespan
+
+class BooleanNode(ElementaryNode):
+ def __init__(self, token, value):
+ super().__init__(token)
self.value = value
assert(isinstance(self.value, bool))
-class IdNode:
+class IdNode(ElementaryNode):
def __init__(self, token):
- self.lineno = token.lineno
- self.colno = token.colno
- self.value = token.value
+ super().__init__(token)
assert(isinstance(self.value, str))
def __str__(self):
return "Id node: '%s' (%d, %d)." % (self.value, self.lineno, self.colno)
-class NumberNode:
+class NumberNode(ElementaryNode):
def __init__(self, token):
- self.lineno = token.lineno
- self.colno = token.colno
- self.value = token.value
+ super().__init__(token)
assert(isinstance(self.value, int))
-class StringNode:
+class StringNode(ElementaryNode):
def __init__(self, token):
- self.lineno = token.lineno
- self.colno = token.colno
- self.value = token.value
+ super().__init__(token)
assert(isinstance(self.value, str))
def __str__(self):
@@ -164,20 +170,23 @@ class StringNode:
class ArrayNode:
def __init__(self, args):
+ self.subdir = args.subdir
self.lineno = args.lineno
self.colno = args.colno
self.args = args
class EmptyNode:
def __init__(self):
+ self.subdir =''
self.lineno = 0
self.colno = 0
self.value = None
class OrNode:
- def __init__(self, lineno, colno, left, right):
- self.lineno = lineno
- self.colno = colno
+ def __init__(self, left, right):
+ self.subdir = left.subdir
+ self.lineno = left.lineno
+ self.colno = left.colno
self.left = left
self.right = right
@@ -189,42 +198,48 @@ class AndNode:
self.right = right
class ComparisonNode:
- def __init__(self, lineno, colno, ctype, left, right):
- self.lineno = lineno
- self.colno = colno
+ def __init__(self, ctype, left, right):
+ self.lineno = left.lineno
+ self.colno = left.colno
+ self.subdir = left.subdir
self.left = left
self.right = right
self.ctype = ctype
class ArithmeticNode:
- def __init__(self, lineno, colno, operation, left, right):
- self.lineno = lineno
- self.colno = colno
+ def __init__(self,operation, left, right):
+ self.subdir = left.subdir
+ self.lineno = left.lineno
+ self.colno = left.colno
self.left = left
self.right = right
self.operation = operation
class NotNode:
- def __init__(self, lineno, colno, value):
- self.lineno = lineno
- self.colno = colno
+ def __init__(self, location_node, value):
+ self.subdir = location_node.subdir
+ self.lineno = location_node.lineno
+ self.colno = location_node.colno
self.value = value
class CodeBlockNode:
- def __init__(self, lineno, colno):
- self.lineno = lineno
- self.colno = colno
+ def __init__(self, location_node):
+ self.subdir = location_node.subdir
+ self.lineno = location_node.lineno
+ self.colno = location_node.colno
self.lines = []
class IndexNode:
def __init__(self, iobject, index):
self.iobject = iobject
self.index = index
+ self.subdir = iobject.subdir
self.lineno = iobject.lineno
self.colno = iobject.colno
class MethodNode:
- def __init__(self, lineno, colno, source_object, name, args):
+ def __init__(self, subdir, lineno, colno, source_object, name, args):
+ self.subdir = subdir
self.lineno = lineno
self.colno = colno
self.source_object = source_object
@@ -233,7 +248,8 @@ class MethodNode:
self.args = args
class FunctionNode:
- def __init__(self, lineno, colno, func_name, args):
+ def __init__(self, subdir, lineno, colno, func_name, args):
+ self.subdir = subdir
self.lineno = lineno
self.colno = colno
self.func_name = func_name
@@ -272,9 +288,10 @@ class IfClauseNode():
self.elseblock = EmptyNode()
class UMinusNode():
- def __init__(self, lineno, colno, value):
- self.lineno = lineno
- self.colno = colno
+ def __init__(self, current_location, value):
+ self.subdir = current_location.subdir
+ self.lineno = current_location.lineno
+ self.colno = current_location.colno
self.value = value
class IfNode():
@@ -296,7 +313,9 @@ class ArgumentNode():
def __init__(self, token):
self.lineno = token.lineno
self.colno = token.colno
+ self.subdir = token.subdir
self.arguments = []
+ self.commas = []
self.kwargs = {}
self.order_error = False
@@ -351,8 +370,8 @@ comparison_map = {'equal': '==',
# 9 plain token
class Parser:
- def __init__(self, code):
- self.stream = Lexer().lex(code)
+ def __init__(self, code, subdir):
+ self.stream = Lexer().lex(code, subdir)
self.getsym()
self.in_ternary = False
@@ -360,7 +379,7 @@ class Parser:
try:
self.current = next(self.stream)
except StopIteration:
- self.current = Token('eof', 0, 0, None)
+ self.current = Token('eof', '', 0, 0, (0, 0), None)
def accept(self, s):
if self.current.tid == s:
@@ -409,7 +428,7 @@ class Parser:
def e2(self):
left = self.e3()
while self.accept('or'):
- left = OrNode(left.lineno, left.colno, left, self.e3())
+ left = OrNode(left, self.e3())
return left
def e3(self):
@@ -422,7 +441,7 @@ class Parser:
left = self.e5()
for nodename, operator_type in comparison_map.items():
if self.accept(nodename):
- return ComparisonNode(left.lineno, left.colno, operator_type, left, self.e5())
+ return ComparisonNode(operator_type, left, self.e5())
return left
def e5(self):
@@ -431,38 +450,38 @@ class Parser:
def e5add(self):
left = self.e5sub()
if self.accept('plus'):
- return ArithmeticNode(left.lineno, left.colno, 'add', left, self.e5add())
+ return ArithmeticNode('add', left, self.e5add())
return left
def e5sub(self):
left = self.e5mod()
if self.accept('dash'):
- return ArithmeticNode(left.lineno, left.colno, 'sub', left, self.e5sub())
+ return ArithmeticNode('sub', left, self.e5sub())
return left
def e5mod(self):
left = self.e5mul()
if self.accept('percent'):
- return ArithmeticNode(left.lineno, left.colno, 'mod', left, self.e5mod())
+ return ArithmeticNode('mod', left, self.e5mod())
return left
def e5mul(self):
left = self.e5div()
if self.accept('star'):
- return ArithmeticNode(left.lineno, left.colno, 'mul', left, self.e5mul())
+ return ArithmeticNode('mul', left, self.e5mul())
return left
def e5div(self):
left = self.e6()
if self.accept('fslash'):
- return ArithmeticNode(left.lineno, left.colno, 'div', left, self.e5div())
+ return ArithmeticNode('div', left, self.e5div())
return left
def e6(self):
if self.accept('not'):
- return NotNode(self.current.lineno, self.current.colno, self.e7())
+ return NotNode(self.current, self.e7())
if self.accept('dash'):
- return UMinusNode(self.current.lineno, self.current.colno, self.e7())
+ return UMinusNode(self.current, self.e7())
return self.e7()
def e7(self):
@@ -473,7 +492,7 @@ class Parser:
if not isinstance(left, IdNode):
raise ParseException('Function call must be applied to plain id',
left.lineno, left.colno)
- left = FunctionNode(left.lineno, left.colno, left.value, args)
+ left = FunctionNode(left.subdir, left.lineno, left.colno, left.value, args)
go_again = True
while go_again:
go_again = False
@@ -516,15 +535,19 @@ class Parser:
a = ArgumentNode(s)
while not isinstance(s, EmptyNode):
+ potential = self.current
if self.accept('comma'):
+ a.commas.append(potential)
a.append(s)
elif self.accept('colon'):
if not isinstance(s, IdNode):
raise ParseException('Keyword argument must be a plain identifier.',
s.lineno, s.colno)
a.set_kwarg(s.value, self.statement())
+ potential = self.current
if not self.accept('comma'):
return a
+ a.commas.append(potential)
else:
a.append(s)
return a
@@ -539,7 +562,7 @@ class Parser:
self.expect('lparen')
args = self.args()
self.expect('rparen')
- method = MethodNode(methodname.lineno, methodname.colno, source_object, methodname.value, args)
+ method = MethodNode(methodname.subdir, methodname.lineno, methodname.colno, source_object, methodname.value, args)
if self.accept('dot'):
return self.method_call(method)
return method
@@ -593,7 +616,7 @@ class Parser:
return self.statement()
def codeblock(self):
- block = CodeBlockNode(self.current.lineno, self.current.colno)
+ block = CodeBlockNode(self.current)
cond = True
while cond:
curline = self.line()