PageRenderTime 49ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/interpreter/core/parser.py

https://github.com/khskrede/mehh
Python | 429 lines | 426 code | 3 blank | 0 comment | 0 complexity | c09e7a39576ce0bb3f00373f46d92042 MD5 | raw file
  1. from pypy.rlib.parsing.ebnfparse import parse_ebnf, make_parse_function
  2. from pypy.rlib.parsing.tree import RPythonVisitor, Nonterminal, Node, Symbol, VisitError
  3. import sys
  4. import haskell.haskell as hh
  5. import module
  6. import copy
  7. ebnf = """
  8. STRING: "\\"[^\\\\"]*\\"";
  9. NUMBER: "\-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][\+\-]?[0-9]+)?";
  10. IGNORE: " |\n";
  11. value: <STRING> | <NUMBER> | <object> | <array> | <"null"> | <"true"> | <"false">;
  12. object: ["{"] (pair [","])* pair ["}"] | ["{}"];
  13. array: ["["] (value [","])* value ["]"] | ["[]"];
  14. pair: STRING [":"] value;
  15. """
  16. def rewrite_id(ident):
  17. # str_ = ident.replace("\"","").replace("zi",".")
  18. # l = str_.split(":")
  19. # l2 = l[1].split(".")
  20. # package=""
  21. # mod=""
  22. # func=""
  23. # if len(l2) == 2:
  24. # package = ""
  25. # mod = l[0]+":"+l2[0]
  26. # func = l2[0]+"."+l2[1]
  27. # elif len(l2) == 3:
  28. # print "l2: ", repr(l2)
  29. # package = l2[0]
  30. # mod = l2[1]
  31. # func = l2[2].replace("zh", "")
  32. # return package, mod, func
  33. str_ = ident.replace("\"", "")
  34. if not (":" in str_ or "." in str_):
  35. return "", "", str_
  36. [package,l] = str_.split(":")
  37. package = package.replace("zm","-")
  38. mod = l.split("zi")
  39. module = ""
  40. for i in range(len(mod)-1):
  41. module += mod[i] + "."
  42. ident_ = mod[len(mod)-1].split(".")
  43. ref = ident_[1]
  44. for i in range(1, len(mod)-1):
  45. ref += "." + ident_[i]
  46. module += ident_[0]
  47. print "---------"
  48. print package
  49. print module
  50. print ref
  51. return package, module, ref
  52. class ForwardReference(object):
  53. def become(self, x):
  54. self.__class__ = x.__class__
  55. self.__dict__.update(x.__dict__)
  56. def replace_vars(self, subst, _):
  57. return self
  58. def get_external(package, mod, name):
  59. package_name = "ghc.libraries." + package + "." + mod
  60. __import__(package_name)
  61. mod = sys.modules[package_name]
  62. ext = getattr(mod, name)
  63. return ext
  64. class AST(RPythonVisitor):
  65. modules = {}
  66. mident=""
  67. def __init__(self, mods=None):
  68. self.modules = mods
  69. def get_ast(self, tree):
  70. node = tree.visit(self)
  71. return node
  72. def visit_object(self, node):
  73. if len(node.children) > 0:
  74. left = node.children[0]
  75. type_ = left.children[0].additional_info
  76. if type_ == "\"%module\"":
  77. self.mident = left.children[1].additional_info.replace("\"","")
  78. mod = module.module()
  79. mod.name = self.mident
  80. self.modules[self.mident] = mod
  81. print self.mident
  82. print "***********"
  83. for vdef in node.children[2].children[1].children:
  84. p = ""
  85. m = ""
  86. f = ""
  87. if not vdef.children[0].children[0].additional_info == "\"%rec\"":
  88. p, m, f = rewrite_id(vdef.children[0].children[1].additional_info)
  89. else:
  90. p, m, f = rewrite_id(vdef.children[0].children[1].\
  91. children[0].children[0].children[1].additional_info)
  92. mod.qvars[ m+"."+f ] = ForwardReference()
  93. func = vdef.visit(self)
  94. mod.qvars[ m+"."+f ].become(func)
  95. print m+"."+f
  96. print "++++++++++++++"
  97. return mod
  98. elif type_ == "\"%data\"":
  99. raise NotImplementedError
  100. elif type_ == "\"%newtype\"":
  101. raise NotImplementedError
  102. elif type_ == "\"qdcon\"" and len(node.children) == 3:
  103. raise NotImplementedError
  104. elif type_ == "\"%rec\"":
  105. func = node.children[0].children[1].visit(self)
  106. func.recursive=True
  107. return func
  108. elif type_ == "\"qvar\"" and len(node.children) == 3:
  109. name = node.children[0].children[1].additional_info
  110. # Skip result/return type ?
  111. t_args = node.children[1].children[1].children[0].children[1].visit(self)
  112. #t_args = node.children[1].children[1].visit(self)
  113. args = []
  114. while type(t_args) == tuple:
  115. args.append(t_args[1])
  116. t_args = t_args[0]
  117. print len(args)
  118. print repr(args)
  119. #args = hh.constr(t_args[0],t_args[1])
  120. exp = node.children[2].children[1].visit(self)
  121. #func = hh.make_application( exp, [args] )
  122. func = hh.function( name, [(args, exp)], recursive=False )
  123. return func
  124. elif type_ == "\"qvar\"" and len(node.children) == 1:
  125. c = node.children[0].children[1].additional_info
  126. print c
  127. print "ååååååååå"
  128. ident = c.replace("\"","")
  129. package, mod, func_name = rewrite_id(ident)
  130. func = 0
  131. if not (package == "main" or package == ""):
  132. func = get_external(package, mod, func_name)
  133. else:
  134. if mod == "":
  135. func = self.modules[self.mident].qvars[func_name]
  136. else:
  137. mident = package + ":" + mod
  138. func = self.modules[mident].qvars[mod+"."+func_name]
  139. print "Wakka"
  140. print func_name
  141. print repr(func)
  142. return func
  143. elif type_ == "\"qvar\"" and len(node.children) == 2:
  144. raise NotImplementedError
  145. elif type_ == "\"qtycon\"":
  146. c = node.children[0].children[1].additional_info
  147. print "-----"
  148. print c
  149. ident = c.replace("\"","")
  150. package, mod, type_name = rewrite_id(ident)
  151. type_ = 0
  152. print package
  153. print mod
  154. print type_name
  155. if not package == "main":
  156. type_ = get_external(package, mod, type_name)
  157. else:
  158. mident = package + ":" + mod
  159. type_ = self.modules[mident].tdefg[mod+"."+type_name]
  160. #print "package name: \"", package_name, "\""
  161. #print "type name: \"", type_name, "\""
  162. return type_
  163. elif type_ == "\"exp\"":
  164. raise NotImplementedError
  165. elif type_ == "\"aexp\"" and len(node.children) == 2:
  166. app = 0
  167. func = node.children[0].children[1].visit(self)
  168. args = node.children[1].children[1].visit(self)
  169. # type1_ = node.children[0].children[1].children[0].children[0].additional_info
  170. type2_ = node.children[1].children[1].children[0].children[0].additional_info
  171. if type2_ == "\"aty\"":
  172. # Type arguments have no operational effect?
  173. return func
  174. # elif type1_ == "\"qdcon\"":
  175. # return hh.make_constructor( func, [args])
  176. else:
  177. return hh.make_application( func, [args] )
  178. elif type_ == "\"aexp\"" and len(node.children) == 1:
  179. return node.children[0].children[1].visit(self)
  180. elif type_ == "\"aty\"" and len(node.children) == 1:
  181. return node.children[0].children[1].visit(self)
  182. elif type_ == "\"lambda\"":
  183. var = node.children[0].children[1].visit(self)
  184. exp = node.children[1].children[1].visit(self)
  185. return hh.function( name, [(var, exp)], recursive=False )
  186. elif type_ == "\"%let\"":
  187. raise NotImplementedError
  188. elif type_ == "\"%case\"":
  189. exp = node.children[1].children[1].visit(self)
  190. of = node.children[2].children[1].visit(self)
  191. alts_ = node.children[3].children[1].children
  192. alts = []
  193. print "MMMMMMMMMMMMMMMMMMMMMMM"
  194. for alt in alts_:
  195. alts.append(alt.visit(self))
  196. print alts
  197. print "MMMMMMMMMMMMMMMMMMMMMMM"
  198. f = hh.function("case", alts)
  199. return hh.make_application(f, exp)
  200. elif type_ == "\"%_\"":
  201. # Default case expression
  202. f = node.children[0].children[1].visit(self)
  203. return ([hh.Var("_")], f)
  204. elif type_ == "\"%cast\"":
  205. raise NotImplementedError
  206. elif type_ == "\"%note\"":
  207. raise NotImplementedError
  208. elif type_ == "\"%external ccal\"":
  209. raise NotImplementedError
  210. elif type_ == "\"%dynexternal ccal\"":
  211. raise NotImplementedError
  212. elif type_ == "\"%label\"":
  213. raise NotImplementedError
  214. elif type_ == "\"lit\"" and len(node.children) == 1:
  215. return hh.CString(node.children[0].children[1].additional_info)
  216. elif type_ == "\"lit\"" and len(node.children) == 2:
  217. pat = node.children[0].children[1].visit(self)
  218. body = node.children[1].children[1].visit(self)
  219. case = ([pat], body)
  220. #print "mmmmmmmmmmmmmmmmmmmmmmmm"
  221. #print case
  222. #print "mmmmmmmmmmmmmmmmmmmmmmmm"
  223. return case
  224. elif type_ == "\"bty\"" and node.children[1].children[0].additional_info == "\"aty\"":
  225. return (node.children[0].children[1].visit(self),
  226. node.children[1].children[1].visit(self))
  227. elif type_ == "\"vbind\"":
  228. return node.children[0].children[1].visit(self)
  229. elif type_ == "\"var\"":
  230. var_name = node.children[0].children[1].additional_info
  231. var_name = var_name.replace("\"","")
  232. ty = node.children[1].children[1].visit(self) # TODO, use this?
  233. var = hh.Var(var_name)
  234. self.modules[self.mident].qvars[var_name] = var
  235. print var_name
  236. print "øøøøøøøøøøøø"
  237. return var
  238. elif type_ == "\"qdcon\"" and len(node.children) == 4:
  239. qdcon = node.children[0].children[1].visit(self)
  240. tbinds_ = node.children[1].children[1].children
  241. tbinds = []
  242. for tbind in tbinds_:
  243. tbinds.append(tbind.visit(self))
  244. vbinds_ = node.children[2].children[1].children
  245. vbinds = []
  246. for vbind in vbinds_:
  247. vbinds.append(vbind.visit(self))
  248. exp = node.children[3].children[1].visit(self)
  249. # TODO ?
  250. return (vbinds, exp)
  251. #return hh.function("", (vbinds, exp))
  252. elif type_ == "\"qdcon\"" and len(node.children) == 1:
  253. package, mod, name = rewrite_id(node.children[0].children[1].additional_info)
  254. if not (package == "main" or package == ""):
  255. return get_external(package, mod, name)
  256. else:
  257. return self.modules[self.mident].qvars[name]
  258. else:
  259. print type_
  260. raise NotImplementedError
  261. def visit_pair(self, node):
  262. left = node.children[0].visit(self)
  263. right = node.children[1].visit(self)
  264. return (left, right)
  265. def visit_array(self, node):
  266. l = []
  267. for child in node.children:
  268. l.append(child.visit(self))
  269. return l
  270. def visit_STRING(self, node):
  271. # TODO: fix this, we can't simply replace
  272. # all: "
  273. str_ = node.additional_info.replace("\"","")
  274. return hh.CString(node.additional_info)
  275. def visit_NUMBER(self, node):
  276. return hh.Integer((node.additional_info.replace("\"","")))
  277. def parse_js( path ):
  278. regexs, rules, ToAST = parse_ebnf(ebnf)
  279. parse = make_parse_function(regexs, rules, eof=True)
  280. doc = open(path, 'r').read()
  281. t = parse(doc)
  282. t = ToAST().transform(t)
  283. return t
  284. def print_dot( path ):
  285. regexs, rules, ToAST = parse_ebnf(ebnf)
  286. parse = make_parse_function(regexs, rules, eof=True)
  287. f = open(path, 'r')
  288. doc = f.read()
  289. t = parse(doc)
  290. t = ToAST().transform(t)
  291. print "digraph parsed {"
  292. print "\n".join(list(t.dot()))
  293. print "}"
  294. # If run directly, generate dot file
  295. if __name__ == "__main__":
  296. if len(sys.argv) > 1:
  297. path = sys.argv[1]
  298. regexs, rules, ToAST = parse_ebnf(ebnf)
  299. parse = make_parse_function(regexs, rules, eof=True)
  300. f = open(path, 'r')
  301. doc = f.read()
  302. t = parse(doc)
  303. t = ToAST().transform(t)
  304. print "digraph parsed {"
  305. print "\n".join(list(t.dot()))
  306. print "}"
  307. else:
  308. print "missing file path"