Advertisement
vietanhlehuu

Untitled

Oct 3rd, 2017
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.09 KB | None | 0 0
  1. package mc.astgen
  2. import org.antlr.v4.runtime.Token
  3. import org.antlr.v4.runtime.CommonTokenStream
  4. import org.antlr.v4.runtime.ParserRuleContext
  5. import java.io.{PrintWriter,File}
  6. import org.antlr.v4.runtime.ANTLRFileStream
  7. import mc.utils._
  8. import scala.collection.JavaConverters._
  9. import org.antlr.v4.runtime.tree._
  10. import mc.parser._
  11. import mc.parser.MCParser._
  12.  
  13. class ASTGeneration extends MCBaseVisitor[Any] {
  14. def higAppend (a: List[AST] , b: List[AST]) = higReverse(a).foldLeft(b) ((x,y) => y::x)
  15. def higReverse (a : List[AST]) = a.foldLeft(List[AST]())((x,y)=> y::x)
  16. //program : declaration+ EOF ;
  17. override def visitProgram(ctx:ProgramContext) =
  18. Program(ctx.declaration.asScala.toList.foldLeft(List[Decl]())(
  19. (a,b) => higAppend(a,b.accept(this).asInstanceOf[List[Decl]]).asInstanceOf[List[Decl]]
  20. ))
  21.  
  22. // declaration: var_declr | fun_declr;
  23. override def visitDeclaration(ctx : DeclarationContext) =
  24. if(ctx.var_declr != null)ctx.var_declr.accept(this)
  25. else List(ctx.fun_declr.accept(this))
  26.  
  27.  
  28.  
  29. // var_declr: pri_type variable (COM variable)* SEMI;
  30. override def visitVar_declr(ctx: Var_declrContext) =
  31. // int a,b,c; => int a, int b và int c
  32. ctx.variable.asScala.toList.map(x =>
  33. if (x.getChildCount() == 1) VarDecl(x.accept(this).asInstanceOf[Id], ctx.pri_type.accept(this).asInstanceOf[Type])
  34. else VarDecl(x.accept(this).asInstanceOf[Id], ArrayType(IntLiteral(x.INTLIT.getText.toInt) ,ctx.pri_type.accept(this).asInstanceOf[Type]))
  35. )
  36.  
  37.  
  38. // pri_type: INTTYPE | STRINGTYPE | BOOLEANTYPE | FLOATTYPE ;
  39. override def visitPri_type(ctx : Pri_typeContext) =
  40. if(ctx.INTTYPE != null ) IntType
  41. else if(ctx.STRINGTYPE != null) StringType
  42. else if (ctx.BOOLEANTYPE != null) BoolType
  43. else FloatType
  44.  
  45.  
  46. // variable : ID | ID LSB INTLIT RSB ;
  47. override def visitVariable(ctx: VariableContext) = Id(ctx.ID.getText)
  48.  
  49.  
  50. // fun_declr : func_type ID LB (para_declr (COM para_declr)* )? RB block_stmt ;
  51. override def visitFun_declr(ctx: Fun_declrContext) =
  52. FuncDecl(Id(ctx.ID.getText),
  53. ctx.para_declr.asScala.toList.foldLeft(List[VarDecl]())(
  54. (a,b) => higAppend(a,b.accept(this).asInstanceOf[List[VarDecl]]).asInstanceOf[List[VarDecl]]),
  55. ctx.func_type.accept(this).asInstanceOf[Type],
  56. ctx.block_stmt.accept(this).asInstanceOf[Stmt]
  57. )
  58.  
  59. // func_type : pri_type | arr_pointer_type | VOIDTYPE ;
  60. override def visitFunc_type (ctx: Func_typeContext) =
  61. if(ctx.pri_type !=null) ctx.pri_type.accept(this)
  62. else if (ctx.VOIDTYPE != null) VoidType
  63. else ctx.arr_pointer_type.accept(this)
  64.  
  65. // arr_pointer_type : pri_type LSB RSB;
  66. override def visitArr_pointer_type( ctx:Arr_pointer_typeContext) =
  67. ArrayPointerType(ctx.pri_type.accept(this).asInstanceOf[Type])
  68.  
  69. // para_declr: (pri_type ID) | (pri_type ID LSB RSB) ;;
  70. override def visitPara_declr (ctx: Para_declrContext) =
  71. if(ctx.getChildCount == 2) List(VarDecl(Id(ctx.ID.getText), ctx.pri_type.accept(this).asInstanceOf[Type]))
  72. else List(VarDecl(Id(ctx.ID.getText) ,ArrayPointerType(ctx.pri_type.accept(this).asInstanceOf[Type])))
  73.  
  74. // block_stmt : LP var_declr* stmt* RP ;
  75. override def visitBlock_stmt( ctx: Block_stmtContext) =
  76. Block(
  77. ctx.var_declr.asScala.toList.foldLeft(List[Decl]())(
  78. (a,b) => higAppend(a,b.accept(this).asInstanceOf[List[Decl]]).asInstanceOf[List[Decl]]
  79. ),
  80. ctx.stmt.asScala.toList.map(_.accept(this).asInstanceOf[Stmt])
  81. )
  82.  
  83. // stmt : if_stmt | do_stmt | for_stmt | break_stmt | continue_stmt | return_stmt | exp_stmt | block_stmt;
  84. override def visitStmt (ctx: StmtContext) =
  85. ctx.getChild(0).accept(this)
  86. // if_stmt : IF LB exp RB stmt ELSE stmt | IF LB exp RB stmt;
  87. override def visitIf_stmt (ctx:If_stmtContext) =
  88. if(ctx.getChildCount == 7)
  89. If(
  90. ctx.exp.accept(this).asInstanceOf[Expr],
  91. ctx.stmt(0).accept(this).asInstanceOf[Stmt],
  92. Some(ctx.stmt(1).accept(this).asInstanceOf[Stmt])
  93. )
  94. else
  95. If(
  96. ctx.exp.accept(this).asInstanceOf[Expr],
  97. ctx.stmt(0).accept(this).asInstanceOf[Stmt],
  98. None
  99. )
  100.  
  101. // do_stmt : DO stmt* WHILE exp SEMI ;
  102. override def visitDo_stmt (ctx: Do_stmtContext) =
  103. Dowhile(
  104. ctx.stmt.asScala.toList.foldLeft(List[Stmt]())(
  105. (a,b) => higAppend(a,List(b.accept(this)).asInstanceOf[List[Stmt]]).asInstanceOf[List[Stmt]]
  106. )
  107. ,
  108. ctx.exp.accept(this).asInstanceOf[Expr]
  109. )
  110. // for_stmt : FOR LB exp SEMI exp SEMI exp RB stmt ;
  111. override def visitFor_stmt(ctx: For_stmtContext) =
  112. For(
  113. ctx.exp(0).accept(this).asInstanceOf[Expr],
  114. ctx.exp(1).accept(this).asInstanceOf[Expr],
  115. ctx.exp(2).accept(this).asInstanceOf[Expr],
  116. ctx.stmt.accept(this).asInstanceOf[Stmt]
  117. )
  118. // break_stmt : BREAK SEMI ;
  119. override def visitBreak_stmt (ctx: Break_stmtContext) =
  120. Break
  121.  
  122. // continue_stmt : CONTINUE SEMI ;
  123. override def visitContinue_stmt(ctx: Continue_stmtContext) =
  124. Continue
  125.  
  126. // return_stmt : RETURN SEMI | RETURN exp SEMI ;
  127. override def visitReturn_stmt(ctx: Return_stmtContext) =
  128. if(ctx.getChildCount() == 2) Return(None)
  129. else Return(Some(ctx.exp.accept(this).asInstanceOf[Expr]))
  130.  
  131. // exp_stmt : exp SEMI;
  132. override def visitExp_stmt (ctx: Exp_stmtContext) =
  133. ctx.exp.accept(this)
  134.  
  135. // exp : term_or (ASSIGN term_or)* ;
  136. // exp : term_or ASSIGN exp | term_or ;
  137. override def visitExp(ctx: ExpContext) =
  138. // ctx.term_or.asScala.toList.tail.zip(ctx.ASSIGN.asScala.toList).foldRight(ctx.term_or(0).accept(this).asInstanceOf[Expr])(
  139. // (x,y) => BinaryOp(x._2.getText,y,x._1.accept(this).asInstanceOf[Expr])
  140. // )
  141. if(ctx.getChildCount()==1) ctx.term_or.accept(this)
  142. else BinaryOp(ctx.ASSIGN.getText,ctx.term_or.accept(this).asInstanceOf[Expr],ctx.exp.accept(this).asInstanceOf[Expr])
  143.  
  144. // term_or : (term_and OR)* term_and;
  145. override def visitTerm_or(ctx: Term_orContext) =
  146. ctx.term_and.asScala.toList.tail.zip(ctx.OR.asScala.toList).foldLeft(ctx.term_and(0).accept(this).asInstanceOf[Expr])(
  147. (x,y) => BinaryOp(y._2.getText,x,y._1.accept(this).asInstanceOf[Expr])
  148. )
  149. // term_and: (term_equal AND)* term_equal ;
  150. override def visitTerm_and (ctx: Term_andContext) =
  151. ctx.term_equal.asScala.toList.tail.zip(ctx.AND.asScala.toList).foldLeft(ctx.term_equal(0).accept(this).asInstanceOf[Expr])(
  152. (x,y) => BinaryOp(y._2.getText,x,y._1.accept(this).asInstanceOf[Expr])
  153. )
  154. // term_equal : term_less EQUAL term_less | term_less NOTEQUAL term_less | term_less ;
  155. override def visitTerm_equal (ctx: Term_equalContext) =
  156. if (ctx.getChildCount() == 1) ctx.term_less(0).accept(this)
  157. else {
  158. BinaryOp(ctx.getChild(1).getText,ctx.term_less(0).accept(this).asInstanceOf[Expr],ctx.term_less(1).accept(this).asInstanceOf[Expr])
  159. }
  160. // term_less : term_add LT term_add | term_add GT term_add | term_add LEQ term_add | term_add GEQ term_add | term_add ;
  161. override def visitTerm_less (ctx: Term_lessContext) =
  162. if (ctx.getChildCount() == 1) ctx.term_add(0).accept(this)
  163. else {
  164. BinaryOp(ctx.getChild(1).getText,ctx.term_add(0).accept(this).asInstanceOf[Expr],ctx.term_add(1).accept(this).asInstanceOf[Expr])
  165. }
  166. // term_add : (term_div (ADD|SUB))* term_div;
  167. // term_add : term_add ADD term_div | term_add SUB term_div | term_div ;
  168. override def visitTerm_add (ctx: Term_addContext) =
  169. if(ctx.getChildCount() == 1 ) ctx.term_div.accept(this)
  170. else {
  171. BinaryOp(ctx.getChild(1).getText,ctx.term_add.accept(this).asInstanceOf[Expr],ctx.term_div.accept(this).asInstanceOf[Expr])
  172. }
  173.  
  174. // term_div : (term_not (DIV|MUL|MOD))* term_not ;
  175. // term_div : term_div DIV term_not | term_div MUL term_not | term_div MOD term_not | term_not
  176. override def visitTerm_div (ctx: Term_divContext) =
  177. if(ctx.getChildCount() == 1 ) ctx.term_not.accept(this)
  178. else {
  179. BinaryOp(ctx.getChild(1).getText,ctx.term_div.accept(this).asInstanceOf[Expr],ctx.term_not.accept(this).asInstanceOf[Expr])
  180. }
  181. // term_not : (SUB|NOT)* term_square ;
  182. // term_not : SUB term_not | NOT term_not | term_square ;
  183. override def visitTerm_not (ctx: Term_notContext) =
  184. if(ctx.getChildCount() == 1 ) ctx.term_square.accept(this)
  185. else {
  186. UnaryOp(ctx.getChild(0).getText,ctx.term_not.accept(this).asInstanceOf[Expr])
  187. }
  188. // term_square : factor LSB exp RSB | factor ;
  189. override def visitTerm_square (ctx: Term_squareContext) =
  190. if(ctx.getChildCount() == 1) ctx.factor.accept(this)
  191. else ArrayCell(ctx.factor.accept(this).asInstanceOf[Expr],
  192. ctx.exp.accept(this).asInstanceOf[Expr])
  193.  
  194. // factor : LB exp RB | INTLIT | FLOATLIT | STRINGLIT | BOOLEANLIT | ID | funcall ;
  195. override def visitFactor( ctx : FactorContext) =
  196. if(ctx.funcall != null) ctx.funcall.accept(this)
  197. else if (ctx.getChildCount() == 3) ctx.exp.accept(this)
  198. else if (ctx.INTLIT != null) IntLiteral(ctx.INTLIT.getText.toInt)
  199. else if (ctx.FLOATLIT != null) FloatLiteral(ctx.FLOATLIT.getText.toFloat)
  200. else if (ctx.STRINGLIT != null) StringLiteral(ctx.STRINGLIT.getText)
  201. else if (ctx.BOOLEANLIT != null) BooleanLiteral(ctx.BOOLEANLIT.getText.toBoolean)
  202. else if (ctx.ID != null) Id(ctx.ID.getText)
  203. // funcall : ID LB (exp (COM exp)*)? RB ;
  204. override def visitFuncall (ctx: FuncallContext) =
  205. CallExpr(Id(ctx.ID.getText),ctx.exp.asScala.toList.map(_.accept(this).asInstanceOf[Expr]))
  206.  
  207.  
  208.  
  209. }
  210.  
  211. ==========================================================MC.G4==============================================
  212. /**
  213. * Student name: Le Huu Viet Anh
  214. * Student ID: 1510054
  215. */
  216. grammar MC;
  217.  
  218. @lexer::header{
  219. package mc.parser;
  220. }
  221.  
  222. @lexer::members{
  223. @Override
  224. public Token emit() {
  225. switch (getType()) {
  226. case UNCLOSE_STRING:
  227. Token result = super.emit();
  228. // you'll need to define this method
  229. throw new UncloseString(result.getText().substring(1, getText().length()));
  230.  
  231. case ILLEGAL_ESCAPE:
  232. result = super.emit();
  233. throw new IllegalEscape(result.getText().substring(1, getText().length()));
  234.  
  235. case ERROR_CHAR:
  236. result = super.emit();
  237. throw new ErrorToken(result.getText());
  238.  
  239. default:
  240. return super.emit();
  241. }
  242. }
  243. }
  244.  
  245. @parser::header{
  246. package mc.parser;
  247. }
  248.  
  249. options{
  250. language=Java;
  251. }
  252.  
  253. program : declaration+ EOF ;
  254.  
  255. declaration: var_declr | fun_declr;
  256.  
  257. var_declr: pri_type variable (COM variable)* SEMI;
  258.  
  259. pri_type: INTTYPE | STRINGTYPE | BOOLEANTYPE | FLOATTYPE ;
  260.  
  261. variable : ID | ID LSB INTLIT RSB ;
  262.  
  263. fun_declr : func_type ID LB (para_declr (COM para_declr)* )? RB block_stmt ;
  264.  
  265. func_type : pri_type | arr_pointer_type | VOIDTYPE ;
  266.  
  267. para_declr: (pri_type ID) | (pri_type ID LSB RSB) ;
  268.  
  269. arr_pointer_type : pri_type LSB RSB;
  270.  
  271. block_stmt : LP var_declr* stmt* RP ;
  272.  
  273. stmt : if_stmt | do_stmt | for_stmt | break_stmt | continue_stmt | return_stmt | exp_stmt | block_stmt;
  274.  
  275. if_stmt : IF LB exp RB stmt ELSE stmt | IF LB exp RB stmt;
  276.  
  277. do_stmt : DO stmt+ WHILE exp SEMI ;
  278.  
  279. for_stmt : FOR LB exp SEMI exp SEMI exp RB stmt ;
  280.  
  281. break_stmt : BREAK SEMI ;
  282.  
  283. continue_stmt : CONTINUE SEMI ;
  284.  
  285. return_stmt : RETURN SEMI | RETURN exp SEMI ;
  286.  
  287. exp_stmt : exp SEMI;
  288.  
  289. //exp : term_or (ASSIGN term_or)* ;
  290. exp : term_or ASSIGN exp | term_or ;
  291.  
  292. term_or : (term_and OR)* term_and;
  293.  
  294. term_and: (term_equal AND)* term_equal ;
  295.  
  296. term_equal : term_less EQUAL term_less | term_less NOTEQUAL term_less | term_less ;
  297.  
  298. term_less : term_add LT term_add | term_add GT term_add | term_add LEQ term_add | term_add GEQ term_add | term_add ;
  299.  
  300. //term_add : (term_div (ADD|SUB))* term_div;
  301.  
  302. //term_div : (term_not (DIV|MUL|MOD))* term_not ;
  303.  
  304. //term_not : SUB term_not | NOT term_not | term_square ;
  305.  
  306. term_add : term_add ADD term_div |term_add SUB term_div | term_div ;
  307.  
  308. term_div : term_div DIV term_not | term_div MUL term_not | term_div MOD term_not | term_not ;
  309.  
  310. term_not : SUB term_not | NOT term_not | term_square ;
  311.  
  312. term_square : factor LSB exp RSB | factor ;
  313.  
  314. factor : LB exp RB | INTLIT | FLOATLIT | STRINGLIT | BOOLEANLIT | ID | funcall ;
  315.  
  316. funcall : ID LB (exp (COM exp)*)? RB ;
  317.  
  318. INTTYPE: 'int' ;
  319.  
  320. VOIDTYPE: 'void' ;
  321.  
  322. FLOATTYPE: 'float' ;
  323.  
  324. STRINGTYPE: 'string' ;
  325.  
  326. BOOLEANTYPE: 'boolean' ;
  327.  
  328. LINECOMMENT: '//'~[\n]* -> skip;
  329.  
  330. BLOCKCOMMENT:'/*' .*? '*/' -> skip;
  331.  
  332. IF : 'if' ;
  333.  
  334. ELSE : 'else' ;
  335.  
  336. DO : 'do' ;
  337.  
  338. WHILE : 'while' ;
  339.  
  340. FOR : 'for' ;
  341.  
  342. BREAK : 'break' ;
  343.  
  344. CONTINUE : 'continue' ;
  345.  
  346. RETURN : 'return' ;
  347.  
  348. INTLIT: [0-9]+;
  349.  
  350. fragment EXPONENT: [eE]'-'?[0-9]+ ;
  351.  
  352. FLOATLIT: ([0-9]+(EXPONENT))|(([0-9]+'.'[0-9]*|'.'[0-9]+)(EXPONENT)?) ;
  353.  
  354. fragment ESCAPE: '\\'[bnfrt\\\'"] ;
  355. STRINGLIT:'"' (~["\\\n]|ESCAPE)* '"'{setText(getText().substring(1, getText().length()-1));};
  356.  
  357. BOOLEANLIT: 'true'|'false';
  358.  
  359. KEYWORD: ('boolean'|'break'|'continue'|'else'|'for'|'float'|'if'|'int'|'return'|'void'|'do'|'while'|'true'|'false'|'string');
  360.  
  361. ID: [_a-zA-Z][_a-zA-Z0-9]* ;
  362.  
  363. ADD: '+';
  364.  
  365. SUB: '-';
  366.  
  367. MUL: '*';
  368.  
  369. DIV: '/';
  370.  
  371. MOD: '%';
  372.  
  373. NOT: '!';
  374.  
  375. OR: '||';
  376.  
  377. AND: '&&';
  378.  
  379. ASSIGN: '=';
  380.  
  381. NOTEQUAL: '!=';
  382.  
  383. EQUAL: '==';
  384.  
  385. LT: '<';
  386.  
  387. GT: '>';
  388.  
  389. LEQ: '<=';
  390.  
  391. GEQ: '>=';
  392.  
  393. LB: '(' ;
  394.  
  395. RB: ')' ;
  396.  
  397. LP: '{';
  398.  
  399. RP: '}';
  400.  
  401. SEMI: ';' ;
  402.  
  403. LSB: '[';
  404.  
  405. RSB: ']';
  406.  
  407. COM: ',';
  408.  
  409. WS : [ \f\t\r\n]+ -> skip ; // skip spaces, tabs, newlines
  410.  
  411. ERROR_CHAR: .;
  412.  
  413. UNCLOSE_STRING: '"' (~["\\\n]|ESCAPE)* EOF? ;
  414.  
  415. fragment IES: '\\'(~[bnfrt\\\'"]) ; // Illegal escape
  416. ILLEGAL_ESCAPE: '"' (~["\\\n]|ESCAPE)*IES ;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement