2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ANTLR4でPL/0インタプリタを作りたい!(1回目 環境構築編)

Last updated at Posted at 2021-01-31

はじめに

「毎月1つは新しい技術に触れよう!」と志した結果、1月のテーマは「ANTLR4」になりました(なんとなく)

  • 多分、1年くらいかけて、PL/0 インタプリタを開発するんだと思います(完成するかな?)
    • なつかしいですね。20年前作りましたね。
    • 上手くいったら、これLLVMに繋げたいなあ……

ANTLR4とは?

ANTLR (ANother Tool for Language Recognition) is a powerful parser generator for reading, processing, executing, or translating structured text or binary files. It's widely used to build languages, tools, and frameworks. From a grammar, ANTLR generates a parser that can build parse trees and also generates a listener interface (or visitor) that makes it easy to respond to the recognition of phrases of interest.

(邦訳)ANTLR(ANother Tool for Language Recognition)は、強力なparser生成器です。構造化された文章やバイナリファイルに対する、読み込み、処理、実行、翻訳に使えます。言語、ツール、フレームワークに広く使われています。grammerから、ANTLRはparserを生成します、oarserがoarse treeを生成し、listener interface(もしくはvisitor)を生成します。これによって、興味のあるフレーズの認識が容易に実現できます。

非常にわかりやすい参考文献

環境構築

環境構築手段はこのあたりを参考に。

$ cd /usr/local/lib
$ curl -O https://www.antlr.org/download/antlr-4.9-complete.jar
export CLASSPATH=".:/usr/local/lib/antlr-4.9-complete.jar:$CLASSPATH"
alias antlr4='java -Xmx500M -cp "/usr/local/lib/antlr-4.9-complete.jar:$CLASSPATH" org.antlr.v4.Tool'
alias grun='java -Xmx500M -cp "/usr/local/lib/antlr-4.9-complete.jar:$CLASSPATH" org.antlr.v4.gui.TestRig'

# Step0. 入力された数字を表示する

grammerファイルを作る。

  • grammerは、ファイル名を合わせる事(ここでは‘Cal'を使っている)
  • あとでsum表示に使うつもりなのでsum
Cal.g4
grammar Cal;
sum : exp ;
exp : NUM ;
NUM : [0-9]+ ;
WS : [\t\r\n]+ -> skip;

コンパイルする

Makefileを使ってサクッとコンパイルする。なお、コンパイルするときはjavacに全部のjavaファイルを同時に喰わせた方がいいっぽい(そうでないとundefinedなsymbolと怒られる)。

Makefile
export CLASSPATH=".:/usr/local/lib/antlr-4.9-complete.jar:$CLASSPATH"
ANTLR4=java -Xmx500M -cp "/usr/local/lib/antlr-4.9-complete.jar:$CLASSPATH" org.antlr.v4.Tool

all: Cal.tokens
        javac *.java

Cal.tokens : Cal.g4
        $(ANTLR4) $<

clean:
        rm -rf *.class

動作確認

grun Cal sum -gui で動作確認できる。なお、入力が終わったら改行してCtrl+Dしないと反映されない。(ここだと、123"改行""Ctrl+D"までやって、画面表示される)。

image.png

Step1. "1+1"に対応してみる。

grammerを見直して、"1+1"にも対応させてみよう。

expは、NUM だけでなく、NUM + NUM も食べれますよ、と。

grammar Cal;
sum : exp ;
exp : NUM |
      exp PLUS exp;
PLUS: '+' ;
NUM : [0-9]+ ;
WS : [\t\r\n]+ -> skip;

image.png

対応する関数を実装

  • exitExp()は、exp要素から抜けるときに実行される関数。
  • つまり、"123 + 456"の場合…3回呼ばれる。
    • 123のexpから抜ける場合
    • 456のexpから抜ける場合
    • ”123+456"のexpから抜ける場合、
  • テストコードの振る舞い
    • 数値のexpから抜けるときには、Stackに数字を積む(push)
    • PLUS含むexpから抜けるときは、Stackから2つ数字を抜き(pop)、加算して数字を積む(push)
  • exitSum()が呼ばれるので、Stackに残った値を表示する。
CalInterfaceListener.java
import org.antlr.v4.runtime.TokenStream;
import org.antlr.v4.runtime.misc.Interval;

import java.util.*;

public class CalInterfaceListener extends CalBaseListener {
    CalParser parser;

    Stack<Integer> mStack;

    public CalInterfaceListener(CalParser parser) {
        this.parser = parser;
        mStack = new Stack<Integer>();
    }

    @Override
    public void exitExp(CalParser.ExpContext ctx) {
        if( ctx.PLUS() != null ){
           int v1 = Integer.parseInt(mStack.pop().toString() );
           int v2 = Integer.parseInt(mStack.pop().toString() );
           Integer v3 = v1 + v2;
           mStack.push ( v3 );
        }
        if( ctx.NUM() != null ){
          mStack.push( Integer.parseInt( ctx.NUM().toString() ) );
        }
    }
    @Override
    public void exitSum(CalParser.SumContext ctx) {
        System.out.println( mStack.pop() );
    }
}

つみのこし・・・

ここに、PL/0のgrammerがあるのではあるが… うん、"*"を使った構文のあたりのやり方が分からない!

if( ctx.XXX() != null ){が0個のときもTRUEになるっぽい。ここらへんは2月の宿題ということで。

expression
   : ('+' | '-')? term (('+' | '-') term)*
   ;

term
   : factor (('*' | '/') factor)*
   ;

factor
   : ident
   | number
   | '(' expression ')'
   ;

ident
   : STRING
   ;

number
   : NUMBER
   ;
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?