Compiler Infrastructureを少し調べる

別のブログにROSE compiler infrastructureのインストールやら使い方やらをまとめていたんだが、思うことあってこの前、それを見ながらUbuntu12.10の環境でインストールを試みた。

しかし、古いバージョンのgccとかboostとかHaskellとか要求されて、あまりに面倒だったので途中であきらめた。FORTRANパーサの具合を見たかっただけなんだが。さくさく動いて、使い勝手はよかったんだけどな。

ROSE compiler infrastructure

COINSもなんでJavaにしたんだろう。antlrJavaだったからだろうか。2012年に久しぶりに関連論文も出てるし、まだまだ頑張ってほしいと心の中で願うのだった。

COINS

書くこと

ほとんど更新していない割に、意外とここをアクセスする人がいるのでびっくりする。書いたことはそこそこ自分の役に立っているけど、他の人の役にも立っているのだろうか。


これから書こうと思っているネタを書いておくことにする。アフィリエイトの設定もしたことだし。

  • ROSEでCプログラムを解析する
  • OpenFortranParserでFortranプログラムを解析するCプログラムを起動する
  • ROOTのTFnの使い方、プログラミングメモ
  • テストデータをYAMLで表現してみる

Fedora 11でcgram

antlrを使用したCパーサcgramが、Fedora 11ではうごかなかった。javaの仕様が変わったのか、-classpath環境変数CLASSPATHの置き換えになっているようだ。

cgram/tests/Makefileを次のように書き換えてうまくいった。

CLASSPATH =  .:..:../examples:../grammars:/usr/share/java/antlr.jar

testall : test test2 test3 test4 test5 test6 test7 test8 test9 \
test10 test11 test12 test13 test14 test15 test16 test17 test18 test19 \
test20 test21 test22 test23 test24 test25 test26 test27 test28 test29 \
test30 test31 test32 test33 test34 test35 test36 test37 test38 test39 \
test40 test41 test42 test43 test44 test45 test46 test47 test48 test49 \
test50 test51 test52 test53 test54 test55 test56 test57 test58 test59 \
test60 test61 test62 test63 test64 test65 test66 test67 test68 test69 \
test70 test71 test72 test73 test74 test75 test76 test77 test78 test79 \
test80 test81 test83 test84 test85 test86 test87

clean : 
	


test : test.c
	java -classpath $(CLASSPATH) Test test.c


test2 : test2.c
	java -classpath $(CLASSPATH) Test test2.c


test3 : test3.c
	java -classpath $(CLASSPATH) Test test3.c


test4 : test4.c
	java -classpath $(CLASSPATH) Test test4.c


test5 : test5.c
	java -classpath $(CLASSPATH) Test test5.c


test6 : test6.c
	java -classpath $(CLASSPATH) Test test6.c


test7 : test7.c
	java -classpath $(CLASSPATH) Test test7.c


test8 : test8.c
	java -classpath $(CLASSPATH) Test test8.c


test9 : test9.c
	java -classpath $(CLASSPATH) Test test9.c


test10 : test10.c
	java -classpath $(CLASSPATH) Test test10.c


test11 : test11.c
	java -classpath $(CLASSPATH) Test test11.c


test12 : test12.c
	java -classpath $(CLASSPATH) Test test12.c


test13 : test13.c
	java -classpath $(CLASSPATH) Test test13.c


test14 : test14.c
	java -classpath $(CLASSPATH) Test test14.c


test15 : test15.c
	java -classpath $(CLASSPATH) Test test15.c


test16 : test16.c
	java -classpath $(CLASSPATH) Test test16.c


test17 : test17.c
	java -classpath $(CLASSPATH) Test test17.c


test18 : test18.c
	java -classpath $(CLASSPATH) Test test18.c


test19 : test19.c
	java -classpath $(CLASSPATH) Test test19.c


test20 : test20.c
	java -classpath $(CLASSPATH) Test test20.c


test21 : test21.c
	java -classpath $(CLASSPATH) Test test21.c


test22 : test22.c
	java -classpath $(CLASSPATH) Test test22.c


test23 : test23.c
	java -classpath $(CLASSPATH) Test test23.c


test24 : test24.c
	java -classpath $(CLASSPATH) Test test24.c


test25 : test25.c
	java -classpath $(CLASSPATH) Test test25.c


test26 : test26.c
	java -classpath $(CLASSPATH) Test test26.c


test27 : test27.c
	java -classpath $(CLASSPATH) Test test27.c


test28 : test28.c
	java -classpath $(CLASSPATH) Test test28.c


test29 : test29.c
	java -classpath $(CLASSPATH) Test test29.c


test30 : test30.c
	java -classpath $(CLASSPATH) Test test30.c


test31 : test31.c
	java -classpath $(CLASSPATH) Test test31.c


test32 : test32.c
	java -classpath $(CLASSPATH) Test test32.c


test33 : test33.c
	java -classpath $(CLASSPATH) Test test33.c


test34 : test34.c
	java -classpath $(CLASSPATH) Test test34.c


test35 : test35.c
	java -classpath $(CLASSPATH) Test test35.c


test36 : test36.c
	java -classpath $(CLASSPATH) Test test36.c


test37 : test37.c
	java -classpath $(CLASSPATH) Test test37.c


test38 : test38.c
	java -classpath $(CLASSPATH) Test test38.c


test39 : test39.c
	java -classpath $(CLASSPATH) Test test39.c


test40 : test40.c
	java -classpath $(CLASSPATH) Test test40.c


test41 : test41.c
	java -classpath $(CLASSPATH) Test test41.c


test42 : test42.c
	java -classpath $(CLASSPATH) Test test42.c


test43 : test43.c
	java -classpath $(CLASSPATH) Test test43.c


test44 : test44.c
	java -classpath $(CLASSPATH) Test test44.c


test45 : test45.c
	java -classpath $(CLASSPATH) Test test45.c


test46 : test46.c
	java -classpath $(CLASSPATH) Test test46.c


test47 : test47.c
	java -classpath $(CLASSPATH) Test test47.c


test48 : test48.c
	java -classpath $(CLASSPATH) Test test48.c


test49 : test49.c
	java -classpath $(CLASSPATH) Test test49.c


test50 : test50.c
	java -classpath $(CLASSPATH) Test test50.c


test51 : test51.c
	java -classpath $(CLASSPATH) Test test51.c


test52 : test52.c
	java -classpath $(CLASSPATH) Test test52.c


test53 : test53.c
	java -classpath $(CLASSPATH) Test test53.c


test54 : test54.c
	java -classpath $(CLASSPATH) Test test54.c


test55 : test55.c
	java -classpath $(CLASSPATH) Test test55.c


test56 : test56.c
	java -classpath $(CLASSPATH) Test test56.c


test57 : test57.c
	java -classpath $(CLASSPATH) Test test57.c


test58 : test58.c
	java -classpath $(CLASSPATH) Test test58.c


test59 : test59.c
	java -classpath $(CLASSPATH) Test test59.c


test60 : test60.c
	java -classpath $(CLASSPATH) Test test60.c


test61 : test61.c
	java -classpath $(CLASSPATH) Test test61.c


test62 : test62.c
	java -classpath $(CLASSPATH) Test test62.c


test63 : test63.c
	java -classpath $(CLASSPATH) Test test63.c


test64 : test64.c
	java -classpath $(CLASSPATH) Test test64.c


test65 : test65.c
	java -classpath $(CLASSPATH) Test test65.c


test66 : test66.c
	java -classpath $(CLASSPATH) Test test66.c


test67 : test67.c
	java -classpath $(CLASSPATH) Test test67.c


test68 : test68.c
	java -classpath $(CLASSPATH) Test test68.c


test69 : test69.c
	java -classpath $(CLASSPATH) Test test69.c


test70 : test70.c
	java -classpath $(CLASSPATH) Test test70.c


test71 : test71.c
	java -classpath $(CLASSPATH) Test test71.c


test72 : test72.c
	java -classpath $(CLASSPATH) Test test72.c


test73 : test73.c
	java -classpath $(CLASSPATH) Test test73.c


test74 : test74.c
	java -classpath $(CLASSPATH) Test test74.c


test75 : test75.c
	java -classpath $(CLASSPATH) Test test75.c


test76 : test76.c
	java -classpath $(CLASSPATH) Test test76.c


test77 : test77.c
	java -classpath $(CLASSPATH) Test test77.c


test78 : test78.c
	java -classpath $(CLASSPATH) Test test78.c


test79 : test79.c
	java -classpath $(CLASSPATH) Test test79.c


test80 : test80.c
	java -classpath $(CLASSPATH) Test test80.c


test81 : test81.c
	java -classpath $(CLASSPATH) Test test81.c


test83 : test83.c
	java -classpath $(CLASSPATH) Test test83.c


test84 : test84.c
	java -classpath $(CLASSPATH) Test test84.c


test85 : test85.c
	java -classpath $(CLASSPATH) Test test85.c


test86 : test86.c
	java -classpath $(CLASSPATH) Test test86.c


test87 : test87.c
	java -classpath $(CLASSPATH) Test test87.c

RubyからC++のクラスを使用する

RubyからC++のクラスを呼び出す例をまとめる。環境は以下の通り。

ANTLR(2.7.7)で生成されたC++によるパーサプログラムを、Rubyから呼び出すために調べたものをまとめてみた。ANTLRも3.0からはRubyも対象言語に含まれているので、わざわざC++のクラスを呼び出すこともなくなるだろう。

クラス定義

まず、C++のクラス定義から。

クラスExmapleのヘッダファイルと定義ファイルを用意する。

Exaple.hpp

// Example.hpp
#ifndef __Example_hpp
#define __Example_hpp

class Example
{
public:
  Example(void);
  ~Example(void);

  char* toUpper(char* str);
  char* toLower(char* str);
  void print(char* str1, char* str2, int num=1);

};

#endif

Example.cpp

// Exmaple.cpp
#include <stdio.h>
#include <iostream>
#include <ctype.h>
#include "Example.hpp"

Example::Example(void)
{
}

Example::~Example(void)
{
}

char* Example::toUpper(char* str)
{
  char* p = str;
  while(*p) {
    *p = toupper(*p);
    p++;
  }
  return str;
}

char* Example::toLower(char* str)
{
  char* p = str;
  while(*p) {
    *p = tolower(*p);
    p++;
  }
  return str;
}

void Example::print(char* str1, char* str2, int num)
{
  int i;
  for(i=0; i<num; i++) {
    std::cout << str1 << " " << str2 << " " << std::endl;
  }
}

呼び出し側のRubyプログラム

次に、Exampleクラスを使用するRubyプログラムex.rbを示す。

#!/usr/bin/env ruby

$:.unshift File.join(File.dirname(__FILE__), ".")
require 'example'

e = Example::Example.new

str1 = "aaa bbb ccc"
p e.toUpper(str1)
p str1
               
p e.toLower(str1)
p str1

e.print("Hello, ", "World!")
e.print("Print", "Message", 3)

C++クラスのラッパーを作成する

SWIGでクラスExampleのラッパーを作成する。

インタフェースファイルの作成

Exampleクラスのラッパーを指定するため、インタフェースファイルexample.iを以下のように作成する。

%module example
%{
#include "Example.hpp"
%}
%include Example.hpp
SWIGの実行

SWIGの実行は以下の通り。ラッパーファイルが生成される。

$ swig -c++ -ruby example.i
$ ls *.cxx
example_wrap.cxx
$

Maikefileを自動生成させる

自分で作ってもいいが、面倒なのでRubyで作ってもらう。
Makefile生成用のRubyプログラムextconf.rbを以下に示す。

extconf.rb

require 'mkmf'
$libs += " -lstdc++ "
create_makefile("example")

実行する。

$ ruby extconf.rb
$

ビルド

makeを実行する。また、SELinuxが設定されている場合は、chconコマンドを実行する必要がある。

$ make
...
$ chcon -t texrel_shlib_t example.so
$

実行

以下に実行結果を示す。

$ ruby ex.ruby
"AAA BBB CCC"
"AAA BBB CCC"
"aaa bbb ccc"
"aaa bbb ccc"
Hello,  World! 
Print Message 
Print Message 
Print Message 
$

まとめ

一連の作業を以下のようにスクリプトにしておくと便利。

$ cat build.sh
/bin/rm -fr *.so *.o *.cxx
swig -c++ -ruby example.i
ruby extconf.rb
make
chcon -t texrel_shlib_t example.so
$

emacsの設定 (Fedora7)

OSをFedora7にしたので、emacsの設定を行う。

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 画面表示
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(setq default-frame-alist
   '((foreground-color . "white")
     (background-color . "black")
;     (top . 2 )
;     (left . 365)
;     (width . 80)
;     (height . 43)
     )
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 日本語
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(load-library "anthy")
(setq default-input-method "japanese-anthy")
(global-set-key "\C-\\" 'anthy-mode)
(set-face-foreground 'anthy-highlight-face "black")
  • 背景色、文字色を変更
  • 日本語入力をkkcからanthyに変更
  • 日本語変換時の候補文字は黒にする


なぜかxemacsの方は、行番号が表示されない。