antlr 生成 java 代码_java – 使ANTLR生成脚本解释器?

本文介绍了如何使用ANTLR 4来创建一个脚本解释器,通过编写语法规则文件和实现监听器,实现了从输入脚本到执行操作的转换。示例包括创建和堆叠块的操作,并提供了详细的Java代码示例。
摘要由CSDN通过智能技术生成

我会简单地评估脚本,而不是生成需要自己编译的Java源文件.

使用ANTLR 4,强烈建议将语法和目标特定代码彼此分开,并将任何目标特定代码放在树监听器或访问器中.

我将快速演示如何使用监听器.

您的示例输入的语法可能如下所示:

文件:blockspeak / BlockSpeak.g4

grammar BlockSpeak;

parse

: instruction* EOF

;

instruction

: create_block

| stack_block

;

create_block

: 'block' NAME 'at' position

;

stack_block

: 'stack' top=NAME 'on' bottom=NAME

;

position

: '(' x=INT ',' y=INT ')'

;

COMMENT

: '#' ~[\r\n]* -> skip

;

INT

: [0-9]+

;

NAME

: [a-zA-Z]+

;

SPACES

: [ \t\r\n] -> skip

;

一些支持Java类:

文件:blockspeak / Main.java

package blockspeak;

import org.antlr.v4.runtime.ANTLRInputStream;

import org.antlr.v4.runtime.CommonTokenStream;

import org.antlr.v4.runtime.tree.ParseTreeWalker;

import java.util.Scanner;

public class Main {

public static void main(String[] args) throws Exception {

Scanner keyboard = new Scanner(System.in);

// Some initial input to let the parser have a go at.

String input = "block A at (0,10) # Create block \"A\" at coordinates (0,10)\n" +

"block B at (0,20) # Create block \"B\" at coordinates (0,20)\n" +

"stack A on B # Stack block A on top of block B";

EvalBlockSpeakListener listener = new EvalBlockSpeakListener();

// Keep asking for input until the user presses 'q'.

while(!input.equals("q")) {

// Create a lexer and parser for `input`.

BlockSpeakLexer lexer = new BlockSpeakLexer(new ANTLRInputStream(input));

BlockSpeakParser parser = new BlockSpeakParser(new CommonTokenStream(lexer));

// Now parse the `input` and attach our listener to it. We want to reuse

// the same listener because it will hold out Blocks-map.

ParseTreeWalker.DEFAULT.walk(listener,parser.parse());

// Let's see if the user wants to continue.

System.out.print("Type a command and press return (q to quit) $");

input = keyboard.nextLine();

}

System.out.println("Bye!");

}

}

// You can place this Block class inside Main.java as well.

class Block {

final String name;

int x;

int y;

Block(String name,int x,int y) {

this.name = name;

this.x = x;

this.y = y;

}

void onTopOf(Block that) {

// TODO

}

}

这个主要的课程是非常自我解释的内联评论.这个棘手的部分是听众应该看起来像什么.那么这里是:

文件:blockspeak / EvalBlockSpeakListener.java

package blockspeak;

import org.antlr.v4.runtime.misc.NotNull;

import java.util.HashMap;

import java.util.Map;

/**

* A class extending the `BlockSpeakBaseListener` (which will be generated

* by ANTLR) in which we override the methods in which to create blocks,and

* in which to stack blocks.

*/

public class EvalBlockSpeakListener extends BlockSpeakBaseListener {

// A map that keeps track of our Blocks.

private final Map blocks = new HashMap();

@Override

public void enterCreate_block(@NotNull BlockSpeakParser.Create_blockContext ctx) {

String name = ctx.NAME().getText();

Integer x = Integer.valueOf(ctx.position().x.getText());

Integer y = Integer.valueOf(ctx.position().y.getText());

Block block = new Block(name,x,y);

System.out.printf("creating block: %s\n",name);

blocks.put(block.name,block);

}

@Override

public void enterStack_block(@NotNull BlockSpeakParser.Stack_blockContext ctx) {

Block bottom = this.blocks.get(ctx.bottom.getText());

Block top = this.blocks.get(ctx.top.getText());

if (bottom == null) {

System.out.printf("no such block: %s\n",ctx.bottom.getText());

}

else if (top == null) {

System.out.printf("no such block: %s\n",ctx.top.getText());

}

else {

System.out.printf("putting %s on top of %s\n",top.name,bottom.name);

top.onTopOf(bottom);

}

}

}

上面的监听器有2个方法定义,映射到以下解析器规则:

create_block

: 'block' NAME 'at' position

;

stack_block

: 'stack' top=NAME 'on' bottom=NAME

;

每当解析器“进入”这样的解析器规则时,将调用侦听器内的相应方法.所以,当调用enterCreate_block(解析器输入create_block规则)时,我们创建(并保存)一个块,当调用enterStack_block时,我们检索该操作涉及的2个块,并将其堆叠在另一个之上.

要查看上述3个类别的操作,请在保存blockspeak /目录下的.g4和.java文件的目录中下载ANTLR 4.4.

打开控制台并执行以下3个步骤:

1.生成ANTLR文件:

java -cp antlr-4.4-complete.jar org.antlr.v4.Tool blockspeak/BlockSpeak.g4 -package blockspeak

2.编译所有Java源文件:

javac -cp ./antlr-4.4-complete.jar blockspeak/*.java

3.运行主类:

3.1. Linux的/苹果机

java -cp .:antlr-4.4-complete.jar blockspeak.Main

3.2.视窗

java -cp .;antlr-4.4-complete.jar blockspeak.Main

这是运行Main类的一个示例会话:

bart@hades:~/Temp/demo$java -cp .:antlr-4.4-complete.jar blockspeak.Main

creating block: A

creating block: B

putting A on top of B

Type a command and press return (q to quit) $block X at (0,0)

creating block: X

Type a command and press return (q to quit) $stack Y on X

no such block: Y

Type a command and press return (q to quit) $stack A on X

putting A on top of X

Type a command and press return (q to quit) $q

Bye!

bart@hades:~/Temp/demo$

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值