Add WIP parser.
This commit is contained in:
parent
da3de495d1
commit
b6a7eefc94
103
parser.py
103
parser.py
|
@ -1,8 +1,19 @@
|
|||
"""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 = ""
|
||||
line_begin = 0
|
||||
|
||||
|
@ -77,10 +88,6 @@ class LLVMLexer(object):
|
|||
t_COMMA = r','
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self.tokens += self.reserved.values()
|
||||
|
||||
|
||||
def t_COMMENT(self, t):
|
||||
r'(;|declare|target).*'
|
||||
pass
|
||||
|
@ -169,20 +176,84 @@ class LLVMLexer(object):
|
|||
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):
|
||||
self.lexer = lex.lex(module=self, **kwargs)
|
||||
|
||||
self.parser = yacc.yacc(module=self, **kwargs)
|
||||
|
||||
def test(self, data):
|
||||
self.lexer.input(data)
|
||||
for tok in self.lexer:
|
||||
print(tok)
|
||||
|
||||
result = self.parser.parse(data, lexer=self.lexer)
|
||||
print(result)
|
||||
|
||||
if __name__ == '__main__':
|
||||
m = LLVMLexer()
|
||||
m.build()
|
||||
data = r'''123 456 c"abc _\2c_ \" \\ and so on" def add sdiv ; some comment
|
||||
qqq
|
||||
p = LLVMParser()
|
||||
p.build()
|
||||
data = r'''
|
||||
define void @tigermain (i64 %U_mainSL_8, i64 %U_mainDummy_9) {
|
||||
ret i64 8
|
||||
}
|
||||
'''
|
||||
m.test(data)
|
||||
p.test(data)
|
||||
|
|
Loading…
Reference in New Issue
Block a user