ANTLR4で生成したファイルをjrubyから触ってみる
ANTLR4でパーサまでを生成してクラスをjarにして、扱うときはJRubyからアクセスしてみます。
あまり、ANTLR4には詳しく説明しません。まだよくわからいので。
準備
Java JDK7準備
以下のページからJDKを落とします。
http://www.oracle.com/technetwork/java/javase/downloads/index.html
Linuxならば、たとえば jdk-7u25-linux-x64.tar.gz を以下のように配置します。
% sudo mkdir /opt % cd /opt % sudo tar xzf ~/Download/jdk-7u25-linux-x64.tar.gz % cd % vi ~/.bashrc ... PATH=$PATH:/opt/jdk1.7.0_25/bin export PATH ... % source ~/.bashrc
javaとjavacとjarのコマンドがあることを確認します。(ex. % which javac)
JRubyの準備
http://jruby.org/
ここでは、jruby-1.7.4 が最新です。
antlr4の準備
まずは、antlr4をダウンロードします。
http://www.antlr4.org/download/
antlr-4.1-complete.jar
Hello.g4 記述
まずは、antlr4用のファイルを用意します。
手始めに、次に記載されているものをそのまま使います。
http://www.antlr.org/wiki/display/ANTLR4/Getting+Started+with+ANTLR+v4
- Hello.g4
// Define a grammar called Hello grammar Hello; r : 'hello' ID ; ID : [a-z]+ ; WS : [ \t\r\n]+ -> skip ;
コンパイル&jar化
- Javaコード生成
% java -jar ./antlr-4.1-complete.jar Hello.g4
Hello.tokens
HelloBaseListener.java
HelloLexer.java
HelloLexer.tokens
HelloListener.java
HelloParser.java
% javac -cp ./antlr-4.1-complete.jar Hello*.java
HelloBaseListener.class
HelloLexer.class
HelloListener.class
HelloParser$RContext.class
HelloParser.class
- Jar化
% mkdir Hello % mv *.class Hello % jar cf Hello.jar -C Hello .
Hello.jar
ここからRubyになります。
hello.rbでListenerコードを書く
同じディレクトリに、以下のファイルがあることを確認してください。
- antlr-4.1-complete.jar
- Hello.jar (作成したjarファイル)
- hello.rb
$:.unshift File.dirname(__FILE__) require 'java' require 'antlr-4.1-complete.jar' require 'Hello.jar' java_import "org.antlr.v4.runtime.ANTLRInputStream" java_import "org.antlr.v4.runtime.CommonTokenStream" class TestHelloListener include Java::Default::HelloListener def enterR(ctx) puts "enterR" end def exitR(ctx) puts "exitR" puts ctx.ID end def enterEveryRule(ctx) end def exitEveryRule(ctx) end def visitTerminal(node) end def visitErrorNode(node) end end input = ANTLRInputStream.new("hello aaa") lexer = Java::Default::HelloLexer.new(input) tokens = CommonTokenStream.new(lexer) parser = Java::Default::HelloParser.new(tokens) parser.addParseListener(TestHelloListener.new) parser.r
JRubyで実行
% jruby hello.rb enterR exitR aaa