Myc
1.添加16进制整数赋值
- 首先修改语法,在g4文件中添加如下语法 - 1 - INT: ('0'|([1-9]([0-9])*))|('0x0'|'0x'[1-9a-f][0-9a-f]*);
- 修改 - MyCBaseListener中- exitAssign()方法,添加一下代码即可:- 1 
 2
 3- if(ctx.expr().value.contains("0x")){
 ctx.expr().value = String.valueOf(Integer.parseInt(ctx.expr().value.substring(2), 16));
 }
2.实现多行注释
- 修改语法,添加跳过多行注释的功能: - 1 - Mul_COMMENT: '/*' ().*? '*/' {skip();};
3.添加除法运算,补充乘除操作功能
- 第一步添加语法规则,如下: - 1 - expr2: expr2 (mix=MIX|div = DIV) expr3 | expr3;
- 补充 - MyCBaseListener中- exitExpr2()方法,关键代码如下:- 1 
 2
 3
 4
 5- ...
 //乘法部分
 CodeOrganizer.getCodeOrganizer().code.add(CodeOrganizer.getCodeOrganizer().line+" MIX " + ctx.expr2().value + " " + ctx.expr3().value + " " + ctx.value);
 //除法部分
 CodeOrganizer.getCodeOrganizer().code.add(CodeOrganizer.getCodeOrganizer().line+" DIV " + ctx.expr2().value + " " + ctx.expr3().value + " " + ctx.value);
4.添加else语句
- 添加语法规则: - 1 - ifStmt: ifKeyWord=IF lsBkt=L_S_BKT expr rsBkt=R_S_BKT llBkt=L_L_BKT stmts lrBtk=R_L_BKT (elseStmt= Else llBkt = L_L_BKT stmts lrBtk=R_L_BKT )? ; //if else语句
- 修改原始if的翻译操作,由于之前使用唯一的 - {来标记if语句不可用,所以单独使用一个- isIf变量来标记- {...}块是否为if语句。同时,添加else语句后,if代码块中的语句执行结束后需要- JUMP操作,调到else代码块之后。相关代码如下:- 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49- public void visitTerminal(TerminalNode node) {
 //左大括号出现在if,else语句中,可使用{和isIs变量共同标识地址
 if (node.getText().equals("{")) {
 if (isIf) {
 CodeOrganizer.getCodeOrganizer().code.add(CodeOrganizer.getCodeOrganizer().line +" COM ??? 0");
 CodeOrganizer.getCodeOrganizer().line++;
 CodeOrganizer.getCodeOrganizer().code.add(CodeOrganizer.getCodeOrganizer().line +" JZ ???");
 CodeOrganizer.getCodeOrganizer().line++;
 } else {
 ArrayList<String> list = CodeOrganizer.getCodeOrganizer().code;
 for (int i = list.size() - 1; i >= 0; i--) {
 String s = list.get(i);
 if (s.contains("???")) {
 list.set(i, s.replace("???", CodeOrganizer.getCodeOrganizer().line + 1 + ""));
 break;
 }
 }
 CodeOrganizer.getCodeOrganizer().code.add(CodeOrganizer.getCodeOrganizer().line + " JUMP !!!");
 CodeOrganizer.getCodeOrganizer().line++;
 }
 }
 if (node.getText().equals("if")) {
 isIf = true;
 }
 if (node.getText().equals("else")) {
 isIf = false;
 }
 }
 public void exitIfStmt(MyCParser.IfStmtContext ctx) {
 ArrayList<String> list = CodeOrganizer.getCodeOrganizer().code;
 String location = ctx.expr().value;
 for (int i = list.size() - 1; i >= 0; i--) {
 String s = list.get(i);
 if (s.contains("!!!")) {
 list.set(i, s.replace("!!!", String.valueOf(CodeOrganizer.getCodeOrganizer().line)));
 }
 if (s.contains("???")) {
 if (s.contains("JZ")) {
 list.set(i, s.replace("???", String.valueOf(i + 2)));
 i--;
 s = list.get(i);
 }
 list.set(i, s.replace("???", location));
 System.out.println(location);
 break;
 }
 }
 }
 }
5.实现四则运算优化
- 优化的目标是让所有相同运算只运算一次,关键是获取 - TemplateVariable时,如果之前已经有了相同运算,则直接给其之前运算的变量名,并消除本次操作。
- 检测之前是否有相同运算操作放在获取临时变量时,代码如下: - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24- public String getTemplateVariable(String op,String l,String r){
 ArrayList<String> list = CodeOrganizer.getCodeOrganizer().code;
 if(list.size()==0)
 return getTemplateVariable();
 for(int i =list.size()-1;i>=0;i--){
 String s = list.get(i);
 if(s.contains(op)){
 StringTokenizer stringTokenizer = new StringTokenizer(s," ");
 stringTokenizer.nextToken();
 if(stringTokenizer.hasMoreTokens()&&stringTokenizer.nextToken().equals(op)){
 if(stringTokenizer.hasMoreTokens()&&stringTokenizer.nextToken().equals(l)){
 if(stringTokenizer.hasMoreTokens()&&stringTokenizer.nextToken().equals(r)){
 if(stringTokenizer.hasMoreTokens()){
 String s1 = stringTokenizer.nextToken();
 variables.add(s1);
 return s1;
 }
 }
 }
 }
 }
 }
 return getTemplateVariable();
 }
- 并且保存一张临时变量的表,便于之后查找临时变量,给变量赋值时使用; 
- 同时,在 - MyCBaseListener中,修改所有四则运算时的代码,添加一步临时变量检测操作,检测该变量是否为新生成的临时变量,如果是新生成的,添加四地址码,否则跳过。这样,优化工作已经完成。
示例
- 输入: - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16- int num;
 num = 0x1;
 num=(-num+1)/(num+2)+num*(num+3);//num混合运算
 if(num+1){
 num=0;
 }else{
 if(num){
 num=1;
 }else{
 num=2;
 }
 }
 /*
 *多行注释
 */- 结果:  
- 输入: - 1 
 2
 3
 4
 5
 6- int x;
 int y;
 x=1;
 y=2;
 int z;
 z=((x+y)*(x+y))*((x+y)*(x+y));- 输出:  
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!