编译器一日一练(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 ; }
}
细心的同学可能注意到了,这个示例比上一个示例代码就多了一个*。不要小瞧这一个*,有了这一个*,运算就可以变成连续运算了。