Add WIP parser.

This commit is contained in:
cfreksen 2017-10-29 02:56:26 +02:00
parent da3de495d1
commit b6a7eefc94
No known key found for this signature in database
GPG Key ID: EAC13EE101008978

103
parser.py
View File

@ -1,8 +1,19 @@
"""Parser for LLVM--.""" """Parser for LLVM--."""
import ply.lex as lex from collections import namedtuple
import ply.lex as lex
import ply.yacc as yacc
# Namedtuples for storing AST
Program = namedtuple('Program', ['tdecls', 'gdecls', 'fdecls'])
FunctionDec = namedtuple('FunctionDec', ['return_type', 'name', 'parameters', 'body'])
FunctionBody = namedtuple('FunctionBody', ['first_block', 'named_blocks'])
Block = namedtuple('Block', ['insns', 'terminator'])
class LLVMParser(object):
# Lexer
class LLVMLexer(object):
current_string = "" current_string = ""
line_begin = 0 line_begin = 0
@ -77,10 +88,6 @@ class LLVMLexer(object):
t_COMMA = r',' t_COMMA = r','
def __init__(self):
self.tokens += self.reserved.values()
def t_COMMENT(self, t): def t_COMMENT(self, t):
r'(;|declare|target).*' r'(;|declare|target).*'
pass pass
@ -169,20 +176,84 @@ class LLVMLexer(object):
t.lexer.skip(1) t.lexer.skip(1)
# Parser
def handle_top_decs(self, smth):
# TODO: Implement
return [], [], smth
def p_program(self, p):
'program : top_decs'
tdecls, gdecls, fdecls = self.handle_top_decs(p[1])
p[0] = Program(tdecls, gdecls, fdecls)
def p_topdecs_fdec(self, p):
'top_decs : fdec top_decs'
p[0] = [p[1]] + p[2]
def p_topdecs_empty(self, p):
'top_decs : '
p[0] = []
def p_fdec(self, p):
'fdec : DEFINE ty AtID LPAREN ty_id_list RPAREN LBRACE fbody RBRACE'
p[0] = FunctionDec(p[2], p[3], p[5], p[8])
def p_ty_simple(self, p):
'''ty : VOID
| I1
| I8
| I32
| I64'''
p[0] = p[1]
def p_ty_id_list_single(self, p):
'ty_id_list : ty PercentID'
p[0] = [(p[1], p[2])]
def p_ty_id_list_multiple(self, p):
'ty_id_list : ty PercentID COMMA ty_id_list'
p[0] = [(p[1], p[2])] + p[4]
def p_ty_id_list_empty(self, p):
'ty_id_list : '
p[0] = []
def p_fbody_one_block(self, p):
'fbody : block'
p[0] = FunctionBody(p[1], [])
def p_block_terminator(self, p):
'block : terminator'
p[0] = Block([], p[1])
def p_terminator_ret_oper(self, p):
'terminator : RET ty operand'
p[0] = (p[2], p[3])
def p_operand(self, p):
'''operand : NULL
| INT
| AtID
| PercentID'''
p[0] = p[1]
def __init__(self):
self.tokens += self.reserved.values()
def build(self, **kwargs): def build(self, **kwargs):
self.lexer = lex.lex(module=self, **kwargs) self.lexer = lex.lex(module=self, **kwargs)
self.parser = yacc.yacc(module=self, **kwargs)
def test(self, data): def test(self, data):
self.lexer.input(data) result = self.parser.parse(data, lexer=self.lexer)
for tok in self.lexer: print(result)
print(tok)
if __name__ == '__main__': if __name__ == '__main__':
m = LLVMLexer() p = LLVMParser()
m.build() p.build()
data = r'''123 456 c"abc _\2c_ \" \\ and so on" def add sdiv ; some comment data = r'''
qqq define void @tigermain (i64 %U_mainSL_8, i64 %U_mainDummy_9) {
ret i64 8
}
''' '''
m.test(data) p.test(data)