A new approach.

pull/15/head
Jussi Pakkanen 11 years ago
parent 2c63f28923
commit eae1e44e0f
  1. 91
      parsertest.py

@ -99,10 +99,28 @@ class Lexer:
line_start = loc
if par_count > 0 or bracket_count > 0:
break
elif tid == 'id':
if match_text in self.keywords:
tid = match_text
yield Token(tid, curline, col)
if not matched:
raise ParseException('lexer', lineno, col)
# Recursive descent parser for Meson's definition language.
# Very basic apart from the fact that we have many precedence
# levels so there are not enough words to describe them all.
# Enter numbering:
#
# 1 assignment
# 2 or
# 3 and
# 4 equality
# comparison, plus and multiplication would go here
# 5 negation
# 6 funcall, method call
# 7 parentheses
# 8 plain token
class Parser:
def __init__(self, code):
self.stream = Lexer().lex(code)
@ -120,20 +138,68 @@ class Parser:
def expect(self, s):
if self.accept(s):
return True
raise ParseException('Unknown token', self.current.lineno, self.current.colno)
raise ParseException('Unknown token ' + self.current.tid, self.current.lineno, self.current.colno)
def parse(self):
self.codeblock()
def statement(self):
if self.accept('lparen'):
self.statement()
self.expect('rparen')
if self.accept('lbracket'):
self.e1()
def e1(self):
self.e2()
while self.accept('assign'):
self.e1()
def e2(self):
self.e3()
if self.accept('or'):
self.e3()
def e3(self):
self.e4()
if self.accept('and'):
self.e4()
def e4(self):
self.e5()
if self.accept('equal'):
self.e5()
def e5(self):
if self.accept('not'):
pass
self.e6()
def e6(self):
self.e7()
if self.accept('dot'):
self.method_call()
self.e6()
elif self.accept('lparen'):
self.args()
self.expect('rbracket')
self.expect('rparen')
self.e6()
def e7(self):
if self.accept('('):
self.expression()
self.rest_statement()
self.expect(')')
else:
self.e8()
def e8(self):
#t = self.current
if self.accept('true'):
return
if self.accept('false'):
return
if self.accept('id'):
return
if self.accept('number'):
return
if self.accept('string'):
return
def args(self):
self.statement()
@ -149,7 +215,7 @@ class Parser:
self.method_call()
def method_call(self):
self.expression()
self.e8()
self.expect('lparen')
self.args()
self.expect('rparen')
@ -177,19 +243,20 @@ class Parser:
self.expect('rparen')
def ifelseblock(self):
if self.current == 'elif':
if self.accept('elif'):
self.statement()
self.expect('eol')
self.codeblock()
def elseblock(self):
if self.current == 'else':
if self.accept('else'):
self.expect('eol')
self.codeblock()
def line(self):
if self.accept('if'):
self.statement()
self.codeblock()
self.ifelseblock()
self.elseblock()
self.expect('endif')
@ -198,12 +265,10 @@ class Parser:
self.statement()
def codeblock(self):
if self.accept('eol'):
return self.codeblock()
cond = True
while cond:
self.line()
cond = self.expect('eol')
cond = self.expect('eol') or self.current == 'elif' or self.current == 'else'
if __name__ == '__main__':
code = open(sys.argv[1]).read()

Loading…
Cancel
Save