Guest User

Untitled

a guest
Feb 24th, 2018
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.28 KB | None | 0 0
  1. import org.antlr.v4.runtime.ANTLRFileStream
  2. import org.antlr.v4.runtime.CommonTokenStream
  3. import org.antlr.v4.runtime.tree.ParseTreeWalker
  4. import java.io.FileNotFoundException
  5. import java.io.IOException
  6. import java.io.PrintWriter
  7. import java.io.UnsupportedEncodingException
  8. import java.util.*
  9.  
  10. class Generator (private val Grammar : String) : GrammarBaseListener() {
  11. private var rules = ArrayList<Rule>()
  12. private var header = ""
  13. private var members = ""
  14.  
  15.  
  16. private var first: MutableMap<String, MutableSet<String>> = HashMap()
  17. private var follow: MutableMap<String, MutableSet<String>> = HashMap()
  18.  
  19. override fun enterStart(ctx: GrammarParser.StartContext) {
  20. header = ctx.HEADER().text
  21. header = header.substring(7, header.length - 2)
  22. members = ctx.MEMBERS().text
  23. members = members.substring(8, members.length - 3)
  24.  
  25. }
  26.  
  27. override fun enterRule_(ctx: GrammarParser.Rule_Context) {
  28. val rule = Rule()
  29.  
  30. // trans attr -- return type
  31. if (ctx.RETURN_SYM() != null) {
  32. var ret = ctx.RETURN_SYM().toString()
  33. ret = ret.substring(1, ret.length - 1)
  34. rule.ret = ret
  35. }
  36.  
  37. if (ctx.SYNTH_ATR() != null) {
  38. var synt = ctx.SYNTH_ATR().toString()
  39. synt = synt.substring(1, synt.length - 1)
  40. rule.synt = synt
  41. }
  42.  
  43. // NON_TERM -- left part
  44. rule.non_term = ctx.NONTERM().toString()
  45.  
  46.  
  47. for (part in ctx.rrule()) {
  48. val rpart = Rpart()
  49. var cnt = 0
  50. loop@for(fulpart in part.fulrule()) {
  51.  
  52. if(fulpart.SYNTH_ATR() != null) {
  53. val synth = fulpart.SYNTH_ATR().toString()
  54. rpart.synth.put(Integer(cnt), synth.substring(1, synth.length - 1))
  55. }
  56.  
  57. if(fulpart.terms() != null) {
  58. val term = fulpart.terms()
  59. if (term.WS() != null) {
  60. continue@loop
  61. }
  62. if (term.SYM() != null) {
  63. val termd = Term(TERMS.SYM, term.SYM().text)
  64. rpart.terms.add(termd)
  65. }
  66. if (term.NONTERM() != null) {
  67. val termd = Term(TERMS.NONTERM, term.NONTERM().text)
  68. rpart.terms.add(termd)
  69. }
  70. if (term.TOKEN() != null) {
  71. val termd = Term(TERMS.TOKEN, term.TOKEN().text)
  72. rpart.terms.add(termd)
  73. }
  74. if (term.EPS() != null) {
  75. val termd = Term(TERMS.EPS, term.EPS().text)
  76. rpart.terms.add(termd)
  77. }
  78. cnt++
  79. }
  80. }
  81. rule.rparts.add(rpart)
  82. }
  83. rules.add(rule)
  84. }
  85.  
  86. @Throws(IOException::class)
  87. fun parseGrammar() {
  88. val lexer = GrammarLexer(ANTLRFileStream(Grammar))
  89. val tokens = CommonTokenStream(lexer)
  90.  
  91. val parser = GrammarParser(tokens)
  92. val tree = parser.start()
  93.  
  94. val walker = ParseTreeWalker()
  95. walker.walk(this, tree)
  96. }
  97.  
  98. private fun ntContainEps(nt: String): Boolean {
  99. return if (!first.containsKey(nt)) false else first[nt].orEmpty().contains("eps")
  100. }
  101.  
  102. private fun getFirst(part: Rpart, ind: Int): MutableSet<String> {
  103. val ret = mutableSetOf<String>()
  104. val terms = part.terms
  105.  
  106. // transform to eps?
  107. var maybe_eps = true
  108. for (i in ind until terms.size) {
  109. val term = terms[i]
  110. if (term.type === TERMS.TOKEN) {
  111. maybe_eps = false
  112. break
  113. } else if (term.type === TERMS.NONTERM) {
  114. if (!ntContainEps(term.v)) {
  115. maybe_eps = false
  116. break
  117. }
  118. }
  119. }
  120. if (maybe_eps) {
  121. ret.add("eps")
  122. }
  123.  
  124. for (i in ind until terms.size) {
  125. val term = terms[i]
  126. if (term.type === TERMS.TOKEN) {
  127. ret.add(term.v)
  128. break
  129. }
  130. if (term.type === TERMS.NONTERM) {
  131. first[term.v].orEmpty().filterTo(ret) { it != "eps" }
  132. if (!ntContainEps(term.v)) {
  133. break
  134. }
  135. }
  136. }
  137. return ret
  138. }
  139.  
  140. private fun calcFirst() {
  141. var changed = true
  142. while (changed) {
  143. changed = false
  144.  
  145. for (rule in rules) {
  146. if (!first.containsKey(rule.non_term)) {
  147. first.put(rule.non_term.orEmpty(), HashSet())
  148. changed = true
  149. }
  150. for (part in rule.rparts) {
  151. // transform to eps?
  152. var maybe_eps = true
  153. for (term in part.terms) {
  154. if (term.type === TERMS.TOKEN) {
  155. maybe_eps = false
  156. break
  157. } else if (term.type === TERMS.NONTERM) {
  158. if (!ntContainEps(term.v)) {
  159. maybe_eps = false
  160. break
  161. }
  162. }
  163. }
  164. if (maybe_eps) {
  165. val s = first[rule.non_term]
  166. if (!s.orEmpty().contains("eps")) {
  167. s!!.add("eps")
  168. changed = true
  169. }
  170. }
  171.  
  172. // cont
  173. for (term in part.terms) {
  174. val s = first[rule.non_term]
  175. if (term.type === TERMS.TOKEN) {
  176. if (!s.orEmpty().contains(term.v)) {
  177. s!!.add(term.v)
  178. changed = true
  179. }
  180. break
  181. } else if (term.type === TERMS.NONTERM) {
  182. if (!first.containsKey(term.v)) break
  183. for (i in first[term.v].orEmpty()) {
  184. if (i != "eps") {
  185. if (!s.orEmpty().contains(i)) {
  186. s!!.add(i)
  187. changed = true
  188. }
  189. }
  190. }
  191. if (!ntContainEps(term.v)) {
  192. break
  193. }
  194. }
  195. }
  196. }
  197. }
  198. }
  199. }
  200.  
  201. private fun calcFollow() {
  202. for (i in rules.indices) {
  203. val rule = rules[i]
  204. follow.put(rule.non_term.orEmpty(), HashSet())
  205. if (i == 0) {
  206. follow[rule.non_term]!!.add("$")
  207. }
  208. }
  209.  
  210. for (rule in rules) {
  211. for (part in rule.rparts) {
  212. val terms = part.terms
  213. for (i in terms.indices) {
  214. val term = terms[i]
  215. if (term.type === TERMS.NONTERM) {
  216. val B = term.v
  217. val ss = getFirst(part, i + 1)
  218. ss.filter { it != "eps" }.forEach {
  219. if(!follow.containsKey(B)) follow.put(B, HashSet())
  220. follow[B]!!.add(it) }
  221. }
  222. }
  223. }
  224. }
  225.  
  226. var changed = true
  227. while (changed) {
  228. changed = false
  229. for (rule in rules) {
  230. val A = rule.non_term
  231. for (part in rule.rparts) {
  232. val terms = part.terms
  233. for (i in terms.indices) {
  234. val term = terms[i]
  235. if (term.type === TERMS.NONTERM) {
  236. val B = term.v
  237. val ss = getFirst(part, i + 1)
  238. if (ss.contains("eps")) {
  239. follow[A].orEmpty().map { follow[B]!!.add(it) }.filter { it }.forEach { changed = true }
  240. }
  241. }
  242. }
  243. }
  244. }
  245. }
  246. }
  247.  
  248. @Throws(FileNotFoundException::class, UnsupportedEncodingException::class)
  249. fun generateParser() {
  250. calcFirst()
  251. calcFollow()
  252.  
  253. val writer = PrintWriter("./src/" + Grammar + "/" + Grammar + "Parser.kt", "UTF-8")
  254. //writer.println("package " + Grammar)
  255. writer.println("import java.text.ParseException;")
  256. writer.println(header)
  257.  
  258. writer.println("class " + Grammar + "Parser constructor(val lex : LexicalAnalyzer) {")
  259. writer.println(members)
  260.  
  261. for (rule in rules) {
  262. val A = rule.non_term
  263.  
  264. writer.println(String.format("class %sContext {", A))
  265. writer.println("var text = \"\"")
  266. if (rule.ret != null) {
  267. val sm = rule.ret
  268. writer.println(sm)
  269. }
  270.  
  271. writer.println("}")
  272.  
  273. // print function
  274. writer.println(String.format("@Throws (ParseException::class)"))
  275. if(rule.synt != null)
  276. writer.println(String.format("public fun %sRule(%s) : %sContext {", A, rule.synt, A))
  277. else
  278. writer.println(String.format("public fun %sRule() : %sContext {", A, A))
  279. writer.println(String.format("val ctx = %sContext()", A))
  280. writer.println("ctx.text = \"\"")
  281. // writer.println("val ntok = lex.token")
  282. writer.println(" when (lex.token) {")
  283.  
  284. for (part in rule.rparts) {
  285. val ss = getFirst(part, 0)
  286. if (ss.contains("eps")) {
  287. ss += follow[A].orEmpty()
  288. ss.remove("eps")
  289. }
  290. var c = 0
  291. for (t in ss) {
  292. c++
  293. if (t !== "$") {
  294. writer.print(String.format("%s", t))
  295. } else {
  296. writer.println(String.format("'$'"))
  297. }
  298. if(c != ss.size)
  299. writer.print(", ")
  300. else
  301. writer.print(" -> ")
  302. }
  303. // print logic
  304.  
  305. // part.terms[0].
  306.  
  307. var cnt = 0
  308. var cnt1 = 0
  309. writer.println("{")
  310. for (term in part.terms) {
  311. val nn = String.format("C%d", cnt)
  312. when {
  313. term.type === TERMS.TOKEN -> {
  314. writer.println("ctx.text += lex.token")
  315. writer.println("lex.nextToken()")
  316. //cnt++;
  317. }
  318. term.type === TERMS.NONTERM -> {
  319. if(part.synth.containsKey(Integer(cnt1)))
  320. writer.println(String.format("val %s = %sRule(%s)", nn, term.v, part.synth[Integer(cnt1)]))
  321. else
  322. writer.println(String.format("val %s = %sRule()", nn, term.v))
  323. writer.println(String.format("ctx.text += %s.text", nn))
  324. cnt++
  325. }
  326. term.type === TERMS.SYM -> {
  327. term.v = term.v.replace("$", "ctx.")
  328. writer.println("run" + term.v.replace("±", "}"))
  329. writer.println("//sym")
  330. }
  331. }
  332. cnt1++
  333. }
  334.  
  335. writer.println("return ctx")
  336. writer.println("}")
  337. }
  338.  
  339. writer.println("else -> throw ParseException(\"? expected at position \" + lex.pos + \" get \" + lex.s[lex.pos], lex.pos)")
  340. writer.println("}")
  341. writer.println("}")
  342.  
  343. for (part in rule.rparts) {
  344. val s = HashSet(getFirst(part, 0))
  345. if (s.contains("eps")) {
  346. s.addAll(follow[A].orEmpty())
  347. s.remove("eps")
  348. }
  349. }
  350. }
  351.  
  352. writer.println("}")
  353. writer.close()
  354. }
  355. }
Add Comment
Please, Sign In to add comment