zl程序教程

您现在的位置是:首页 >  工具

当前栏目

编译器一日一练(DIY系列之连续加减法)

编译器 系列 连续 DIY 一日
2023-09-27 14:27:10 时间

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

        上一篇我们说到了怎么用javacc写一个加法器的解析工具。今天继续,可以在这个基础上看一下怎么做一个连续加减法的工具。

        代码链接:https://github.com/feixiaoxing/DIYCompiler

1、减法工具

        剑法工具比较简单,就是在原来加法的基础之上,修改成-就可以了。我们可以看一下对应生成的Adder.jj文件,

options {
    STATIC = false;
}
 
PARSER_BEGIN(Adder)
import java.io.*;
public class Adder {
    public static void main(String[] args) {
        for (String arg : args) {
            try {
                System.out.println(evaluate(arg));
            } catch (ParseException ex) {
                System.err.println(ex.getMessage());
            }
        }
    }
 
    public static long evaluate(String src) throws ParseException {
        Reader reader = new StringReader(src);
        return new Adder(reader).expr();
    }
}
PARSER_END(Adder)
 
SKIP: { <[" ", "\t", "\r", "\n"]> }
TOKEN: {
    <INTEGER: (["0"-"9"])+>
}
 
long expr() throws NumberFormatException :
{
    Token a ;
    Token b ;
    int value = 0 ;
}
{
    a = <INTEGER> "-" b = <INTEGER>
    { 
		value = Integer.parseInt( a.image ) - Integer.parseInt(b.image); 
	}
    <EOF>
    { return value ; }
}

2、加法或者减法

        这个比较有意思,其实就相当于可以做加法,也可以做减法,但是每次只能做一个。所以,这里Adder.jj要做一点修改,

options {
    STATIC = false;
}
 
PARSER_BEGIN(Adder)
import java.io.*;
public class Adder {
    public static void main(String[] args) {
        for (String arg : args) {
            try {
                System.out.println(evaluate(arg));
            } catch (ParseException ex) {
                System.err.println(ex.getMessage());
            }
        }
    }
 
    public static long evaluate(String src) throws ParseException {
        Reader reader = new StringReader(src);
        return new Adder(reader).expr();
    }
}
PARSER_END(Adder)
 
SKIP: { <[" ", "\t", "\r", "\n"]> }
TOKEN: {
    <INTEGER: (["0"-"9"])+>
}
 
long expr() throws NumberFormatException :
{
    Token a ;
    Token b ;
    int value = 0 ;
}
{
    
	a = <INTEGER>
	{
		value = Integer.parseInt(a.image); 
	}
	
	(
	 "+" b = <INTEGER>
    { 
		value += Integer.parseInt(b.image); 
	} |
	"-" b = <INTEGER>
    { 
		value -= Integer.parseInt(b.image); 
	}
	)
    <EOF>
    { return value ; }
}

        通过上面的规则分析,可以看到第一个INTEGER已经被放到了外面。第二个INTEGER中添加了一个|,这样就可以做选择题了。不管是输入+运算,还是-运算,都可以开始计算。

3、连续加减法

        所谓的连续加减法,就是在上面加、减法的基础上增加一个连续运算。大家可以看一下,两个Adder.jj文件的变化。

options {
    STATIC = false;
}
 
PARSER_BEGIN(Adder)
import java.io.*;
public class Adder {
    public static void main(String[] args) {
        for (String arg : args) {
            try {
                System.out.println(evaluate(arg));
            } catch (ParseException ex) {
                System.err.println(ex.getMessage());
            }
        }
    }
 
    public static long evaluate(String src) throws ParseException {
        Reader reader = new StringReader(src);
        return new Adder(reader).expr();
    }
}
PARSER_END(Adder)
 
SKIP: { <[" ", "\t", "\r", "\n"]> }
TOKEN: {
    <INTEGER: (["0"-"9"])+>
}
 
long expr() throws NumberFormatException :
{
    Token a ;
    Token b ;
    int value = 0 ;
}
{
    
	a = <INTEGER>
	{
		value = Integer.parseInt(a.image); 
	}
	
	(
	 "+" b = <INTEGER>
    { 
		value += Integer.parseInt(b.image); 
	} |
	"-" b = <INTEGER>
    { 
		value -= Integer.parseInt(b.image); 
	}
	)*
    <EOF>
    { return value ; }
}

        细心的同学可能注意到了,这个示例比上一个示例代码就多了一个*。不要小瞧这一个*,有了这一个*,运算就可以变成连续运算了。