antlr4を使う(2)

シーマークすずきです。

前回の続きで、antlr4が生成したパーサーソースをjavaから呼び出して、利用してみます。

■ eclipseのGradleプロジェクト作成

build.gradleは以下としました。antlr4が生成するソースをjp.co.seamark.csv.generatedパッケージに吐かれる様にします。また、構文木を捜索する方式は、リスナー方式とビジター方式がありますが、今回は、リスナー方式としました。

 

■ CSVの単純なパース

前回生成したソースのCSVBaseListenerクラスを拡張します。簡単にcsvファイルの全行をString型で受け取る方式とします。まずは、構文木の文字列形式に変換して返すだけにします。

実行すると、以下の様に前回grunでコンソール出力した結果と同じ結果が表示されました。(注意)fileToString()は割愛します。

テスト用のtest.csvは前回と同じ以下。

CSVSimpleParserの実行結果。

>AST=>(file (hdr (row (field user.name) , (field string#!user.age) , (field *omit*user.gender) \n)) (row (field suzuki) , (field 50) , (field male) \n) (row (field ange) , (field 12) , (field female) \n) (row (field seamark) , (field 20) , (field male) \n))

■ 構文木をウォークスルーしてみましょう

ParseTreeクラスをParseTreeWalkerクラスでwalk()することで、構文木の各構文ノードへのenter,とexitのリスナーイベントが呼ばれますのでメソッドをOverrideすることで自分用に処理を追加できます。

プログラムで処理する場合、構文ルール毎にexitほげほげのタイミングが分かりやすいでしょう。以前のCSV.gの文法を記述した際、構成要素はfieldというルールで各行rowが構成される、としました。fieldの構文ノードを抜けるタイミング、つまり、exitField()の関数でrowリストにfield文字列を追加していきます。先頭行のヘッダー行として、headerに、取り込みたい場合、exitHdr()のタイミングです。各CSV行の行毎のタイミングであれば、exitRow()となります。headerが空でない場合にCSVデータをheaderのラベルと一緒にMapに取り込みましょう。

■ JSON形式に変換してみる。

List<Map<String,String>> rowsに全ての行が取り込まれましたので、exitFile()をOverrideしてJSON形式に出力してみましょう。以下のメソッドを追記します。

出力結果は、以下。

もう少し考慮すれば、以前のNode.jsのcsvtojson.jsと同じ様な変換ができそうです。”string#!”や”number#!”がヘッダーに付いていれば、JSON型を文字列、数値型にするとか、”*omit*”が付いていれば、JSON出力しない、とか。残りは、後日。

antlr4を使う(1)

シーマークすずきです。

antlr4について少しメモをまとめておく。

  • antlr4とは

ANTLR (ANother Tool for Language Recognition)は強力なコンパイラコンパイラです。コンパイラとは、簡単に言えば、人が理解しやすい表現の記述から、目的に合わせてコンピュータが処理しやすい形式に変換することです。コンパイラは通常次のステップを行います。まず初めに、「元になるソースから構造を発見する」次に「目的に合わせて変換」します。後者の目的部分は、各コンパイラプログラムによって様々ですが、初めのステップは、一般的には更に次の処理に分割されます。

  1. ソースからトークン(token)に分割・分解し、トークンを発掘する(字句解析)
  2. 複数のトークンを構文に従って木構造に構造化(組み上げ)する(構文解析)

コンパイラコンパイラは、上記の字句解析と構文解析するコンパイラプログラム(別名パーサーと呼ばれています)を作成するためのコンパイラです。ANTLRを使い、構文定義(grammarファイル)を記述し、その定義に従って、つまり、grammarファイルをソースにして字句解析し構文解析するためのプログラムソースを生成してくれます。開発者は目的に応じて木構造を捜索したり、変換したりすれば良いのです。ANTLRをパーサージェネレーターと呼ぶ場合もあるようです。

  • 何ができる?

たとえば、JavaやC++のソースをパースするプログラムを作成することも可能です。他にも、日本語で「式」を定義し、それを計算するというプログラムも作成できます。”(上底 + 下底) * 高さ / 2.0”などの式の文字列をパースして、意味のある単位の「変数」や「演算子」や「括弧」のトークンに分割し、定義した優先順位でトークンを組上げて、それを順番に変数を数値変換して計算を行うための計算機プログラムを作成することもできます。

  • 使ってみる

パーサーは文法が定義できればほぼ何でも作成できます。HTML、JSONなどのデータファイルをパースするプログラムも面白いですが、ここでは、簡単なcsvのパーサーを作成してみましょう。まず初めに文法定義をします。以下に簡単なcsvのantlr4の文法定義です。CSV.gとファイル名を付けます。

CSVファイルの構造の定義をしています。CSVファイルは、ヘッダー(hdr)と複数の行(row)でできている、としています。複数個(0個以上)の行である表現は’+’が付いているからです。次に、ヘッダー(hdr)は1行(row)で構成されると定義しています。行(row)の定義です。行はフィールド(fieldがカンマ(,)で区切られて複数あること、行の終端は’\r”\n’或は’\n’である、と定義しています。’*’は0回以上の繰り返しです。定義はまだ、続きます。フィールド(field)はTEXTかSTRINGのいずれかで構成されると宣言しています。TEXTは、カンマ(,)か(’\n’)か(‘\r’)の何れでもない文字の0個以上の繰り返しです、としています。つまりTEXTは数値や英数文字も全てです。STRINGは、ダブルクオートで囲われていて、連続する2つのダブルクオートか1つのダブルクオート以外の全ての文字です。

文法定義ファイルをantlr4コマンドに以下のようにわたします。

> antlr4 CSV.g

> ls

CSV.g CSV.tokens CSVBaseListener.java
CSVLexer.java CSVLexer.tokens CSVListener.java CSVParser.java

生成されたJavaソースをjavacでコンパイルします。早速、antlr4の検証ツールgrunで試してみましょう。

> grun CSV file -tree

user.name, user.age, *omit*user.gender
suzuki,50,male
ange,12,female
seamark,20,male

Control+Dで、以下がコンソールに出力されます。

(file (hdr (row (field user.name) , (field user.age) , (field *omit*user.gender) \n)) (row (field suzuki) , (field 50) , (field male) \n) (row (field ange) , (field 12) , (field female) \n) (row (field seamark) , (field 20) , (field male) \n))

階層をGUI表示させたい場合は、-treeを-guiとします。

> grun CSV file -gui

user.name, user.age, *omit*user.gender
suzuki,50,male
ange,12,female
seamark,20,male

Control+Dで以下の画面表示がされます。

antlr4_parse_tree_1

  • 今後

次回は、grunを使わずに、javaプログラムからantlr4で生成したソースを呼び出して利用してみます。

 

csvからjsonへ変換する(メモ1)

シーマークすずきです。

開発プロジェクトでいつも取り組むことのひとつが、プログラムのテストのために、テストデータを用意することです。ここでは、先日使ってみたcsvtojsonというライブラリがよく出来ていたので、簡単に紹介します。

■テストデータの元ネタはCSVで作っとく

テストデータをプログラマーが書くことは良くありますよね。入力データと結果期待値データ。プログラムに喰わせる訳ですから、プログラムが読み易いフォーマットが良いのですが、お客さんにレビューしてもらう都合上、お客さんには表計算ソフトの書式で出したいことが良くあります。そこでよく利用されるのはcsv書式です。

■csvtojsonが便利

先日も参加している開発チーム内で、テストプログラムを開発している担当者側はJSONで欲しい。テスト仕様書作成担当者は、表計算ソフトで作成中です、っと。つまり、どっかで誰かが、csvからjsonに変換する必要が発生しました。csvは構造を持たないフラット構造ですが、jsonは構造を持つための階層構造。ネットで少し調べていたら、 node.jsのライブラリでcsvtojsonがよく出来ていそうだったので、使ってみました。

参考URL: https://github.com/Keyang/node-csvtojson

■インストール

上記URLからgit cloneして利用できます。または、 npmでインストール可能です。

>npm install -g csvtojson

■動かしてみる

csvファイルのサンプルは以下のsample.csvです。

$ cat sample.csv
user.name, user.age, user.gender
suzuki,50,male
ange,12,female
seamark,20,male

変換してみましょう。

$ bin/csvtojson < sample.csv
[
{“user”:{“name”:”suzuki”,”age”:50,”gender”:”male”}}
,
{“user”:{“name”:”ange”,”age”:12,”gender”:”female”}}
,
{“user”:{“name”:”seamark”,”age”:20,”gender”:”male”}}

]

とっても簡単です。出力したくない列には、*omit* を指定すれば、jsonに変換しません。

$ cat sample.csv
user.name, user.age, *omit*user.gender
suzuki,50,male
ange,12,female
seamark,20,male

*omit*指定したuser.gender列は以下の通り変換されません。

$ bin/csvtojson < sample.csv
[
{“user”:{“name”:”suzuki”,”age”:50}}
,
{“user”:{“name”:”ange”,”age”:12}}
,
{“user”:{“name”:”seamark”,”age”:20}}

]

これのおかげで、テスト仕様書をレビュー後、直ぐにjson変換ができました。

求む!「一緒に仕事をし、一緒に成長してくれる仲間」

三浦です。
採用プロジェクトの進捗報告です。
まずは「求める人材像」というものを明らかしていかないといけません。

全社員(といっても全部で7人ですが)で、あーだ、こーだと議論を重ねてきて、ようやく大まかな「人材像」を描き出すことができました。
ただし、今回の採用プロジェクトは、全社員が賛同、納得して行っていくものですので、今後も議論を重ねながら、少しでも違和感を感じる部分や、条件の追加や修正が必要であれば、適宜変更していくことになると思います。
ということで、現時点での「求める人材像」&「シーマークでの仕事と職場環境についての自己紹介」になります。
シーマークでの未来をご一緒できるまだ見ぬどなたかの心に届きますように。
ご興味のある方は、こちらからお気軽にお問い合わせください。

■こんな方にオススメです

「開発現場での仕事にこだわりたい!」
「もっと自分の技能を高めることのできる環境が欲しい」
「大きな組織の決まった仕事でなく、自分の工夫と裁量のある仕事をしたい」
「経験はないけど自分でシステムを構築していく技能を身に着けたい」
「フラットで風通しの良い組織で余計なストレスなく働きたい」

役員3人と従業員4人の小さな会社です。
役員も含め全員が、システム開発、運用、企画の現場に携わるものであり、第一線のエンジニアとして活躍し、新たな技術への挑戦を続けております。
自らシステムを構築するエンジニアとしての技量を発揮し、その技量を高める機会とサポートを提供します。

■仕事内容

・受託したシステムの設計・開発
・システムの性能やセキュリティの診断とコンサルティング
・自社システム、サービスの運用とメンテナンス
・新たな自社システム、サービス等の企画立案と開発

シーマークには、現在2つの事業があります。
1つはエンタープライズ事業であり、受託したシステムの設計・開発や、コンサルティングを行います。エンジニアとしての主要な業務はこの事業部でのものになります。
もう一つは、エリアコミュニティ事業であり、自社運営のコミュニティサイト上に掲載する広告の売上の獲得をビジネススキームとしています。このサイトの運用とメンテナンス、新機能の開発を担っていただくことがあります。
また、常に全社員から、新たなシステムやサービスの企画提案や、新しい技術習得のための研究活動の提案の機会を設けており、様々な新たな取組について、時間と予算を確保し、取り組んでいただくことも可能です。
これまでにも、独自のJ2EE開発フレームワークの開発、家族単位でのSNSサイトの構築、訪問介護サービス用のタブレットによる記録システムの構築、全文検索システム研究のための海外渡航研修などを行っています。

■期待する技能・経験等

・システム、アプリケーションの構築に興味があること
・好奇心をもって必要な技術情報を収集する能力と姿勢
・工夫を凝らして業務にあたる姿勢

言語を問わず、何らかのシステムやアプリケーションを自分で構築した経験があることが望ましいですが、仕事を通じて、エンジニアとしての技能を身につけるために、自ら進んで情報を集めて学んでいける気持ちをお持ちの方であれば歓迎いたします。もちろん学びと経験のサポートはお任せください。
年齢は不問です。
なお、現在ほとんどの業務が日本語でのコミュニケーションの中で行われているため、日本語での円滑なコミュニケーションができることは必要です。

■待遇条件

・試用期間3ヶ月
・技量、経験に応じて年俸制 400万~1000万円(夏冬各2ヶ月分の賞与含む)
・通信手当月額1万円
・保険完備
・夏期休暇および年末年始休暇あり
・完全週休2日制(土・日休み)・祝祭日休み
・有給休暇制度あり

■職場環境・業務環境

・自社オフィス内または案件によりクライアントオフィス

クライアントオフィスでの業務となる場合も、組織としての相談サポート体制を確保し、クライアントへの積極的な提案力を持つため、原則として複数メンバーのチームでの対応とするとともに、週1度程度の自社オフィスでの勤務とします。