Shiki’s Weblog

日本語プログラミング言語と簡約日本語 (4)

2019/02/15 2019/02/16 一部、加筆訂正。2019/02/18 「プログラム全体の構成」を追加。

 前回は、OrotiでかいたプログラミムをPythonにかきなおすプログラムを紹介しました。このような、あるプログラミング言語でかかれたプログラムをべつのプログラミング言語に翻訳するプログラムをトランスパイラーとよんだりします。前回のトランスパイラーはPythonでかいていました。いまは開発がすすんで、OrotiのトランスパイラーをOrotiでかけるようになりました。

 今回は、いまつかっているOrotiの文法と、Orotiでかいたトランスパイラーの紹介をします。

Orotiの文法

 いまのところ、Orotiは簡約日本語のステップIIを基準に設計しています。ステップIIの特徴は、

 「ステップIIまでは動詞は活用を教えず、すべてマスをつけて、マスの活用だけとすることとしています。」(p.9)

という部分でしょう。マス形をつかうと、動詞は連用形だけでいろいろな文をつくることができます。そのため、Orotiでつかう文法もかんたんなものになっています。

 将来のOrotiでは、ステップIII以降をとりいれて、動詞の活用形をつかえるようにしてもおもしろいかもしれません。

文の基本構造

 つぎの例文は、Orotiのじっさいのプログラムのなかの一文です。

(例文)

辞書の助詞一覧に助詞をくわえます。

 Orotiの基本的な文はつぎのような構造になっています。

(文): (項)……(項)(V)ます。

 (項)……(項)というかきかたは、(項)がひとつ以上ならんでいることをあらわします。ここでは、……の意味をそういう約束にします、ということです。

 (V)には、動詞の連用形がはいります。例文では、「くわえます」という動詞の「くわえ」の部分です。

 (項)の「項」という用語は、英語だとargumentです。プログラマーだと、引数というargumentの訳語のほうをよくつかうかもしれません。

 Orotiのひとつひとつの項のなかは、つぎのような構造になっています。

(項): (式)(助詞)

 あらためて例文をみてみます。「くわえます」という動詞は項をふたつとります。項のなかの助詞は、ひとつは「に」、もうひとつは「を」です。これを図にすると、つぎのようになります。

(式)に(式)をくわえます。

 このような動詞と項のくみあわせを文型といいます。

 プログラムのなかで動詞をつかうとき、項の順番はいれかえてもかまいません。つぎのふたつの文は、まったくおなじ意味になります。

(例: 項のいれかえ)

セットに要素をくわえます。

要素をセットにくわえます。

 そのかわり、動詞のそれぞれの項では、べつべつの助詞がつかわれています。

 Orotiでつかう文型はそれほどおおくありません。それについても、今回あとでみていきます。

 ふつうの日本語の文型には主体を指定する成分がでてきます。Orotiでは主体を明示的にかくことはありません。主体は文脈からわかるからです。

 プログラミング言語では、プログラムの文のことを命令文とよくいいます。命令文では、ふつうの英文でも、主語が省略されているのと似たような感じです。ただ日本語で、「~しろ」とか、「~せよ」といった文がならんでいる文章は、よむのも、かくのも、あまり気がすすみません。

 日本語では、主語を省略するために命令文にする必要はありません。Orotiのプログラムは、すこしていねいすぎるくらいの「です・ます」調になります。そろばんでも、さいしょに「ねがいましては」というのですから、日本語では、ちょうどよいくらいではないでしょうか。

 さいしょの例文のなかの「辞書の助詞一覧」はになります。「辞書の助詞一覧」は、「の」で「辞書」のなかの「助詞一覧」をとりだす式というふうにかんがえます。「i + j」のような値を計算する式ももちろん式です。

 ほかにも、「辞書」のようななにかの名前や文字列だけでも式になります。Orotiの文字列は、文字列を、かぎかっこ(「」)か、二重かぎかっこ(『』)でかこってあらわします。

(例: 文字列)

「こんにちは」
『漢字(かんじ)』

オペレーター(演算子)

 「i + j」のなかの「+」 や、「辞書の助詞一覧」のなかの「の」はオペレーターといいます。なにかの操作をあらわす記号のことで、演算子ともいいます。

 演算子の「子」は、「売り子」とか「おどり子」とかとおなじ種類の接尾辞でしょう。演算子のかわりに、「あやつり子」ということばをつくっていたら、おぼえやすかったかもしれません。

 よくつかうオペレーターはつぎのようなものです。

オペレーター 意味
~の(属性) 属性のとりだし
~[(そえ字)] インデクシング操作
~[(はじまり):(おわり)] スライス操作
*、/、%、+、- かけ算、わり算、あまり算、たし算、ひき算
<、<=、==、!= よりちいさい、おなじかよりちいさい、ひとしい、ひとしくない

 Orotiでは、Pythonの演算子もそのままつかえます。[はじまり:おわり]という形式のスライス操作は、Pythonでつかわれているものです。文字列を操作するときに、とてもべんりなオペレーターです。

「こんにちは、世界。」[6:-1] → 「世界」   # 6文字目から、おわりから1文字目のてまえまで

 「こんにちは」の「こ」は0文字目とかぞえるのが、OrotiやPythonなどのプログラミング言語での約束です。

代入文

※ 代入文は、前回までの形から文型をかえました。

 代入文の基本形は、

(代入文): (式)を(式)にいれます。

です。たとえば、

得点 + 1を結果にいれます。

といったぐあいです。変数は、こどもには、よく箱にたとえておしえているようです。動詞も「いれます」にしておくと、箱と対応がとれます。

 文の結果(もどり値)を変数に代入するときは、つぎの形をつかいます。

(代入文): (項)……(項)(V)まして、(式)にいれます。

たとえば、

文字列から「(」をみつけまして、位置にいれます。

といったぐあいです。

 文字列にたいして「みつけます」という動詞をつかうと、何文字目という結果がかえってきます。文字列が『漢字(かんじ)』だとすると、2が位置にいれられます。文字列のなかに、さがしたい文字がみつからなければ、-1がかえってきます。

 この代入文は、基本形の文と、「(式)にいれます」という代入文を、「て、」でつなげた形になっています。これを、テ形といいます。ふつうの日本語では、テ形をつかって、いくらでもながい文をつくれますが、Orotiでは、「て、」をつかえるのは一回だけにしています。

 仕ごとでつかわれているプログラムでは、ながすぎる文をつかうことは、しばしば禁止されています。ほかのひとが、プログラムをよんで理解するのがむずかしくなってしまうからです。

基本動詞

 Orotiでは、Pythonの基本的なメソッドを基本動詞としてつかえるようにしてあります。わかってしまえば、それぞれ日本語で文字どおりの処理をする動詞です。くわしくは、『Pythonチュートリアル』などをみてみてください。

Orotiの基本動詞 対応するPythonのメソッド
(式)に(式)が あります __contains__ (inの内部でつかわています)
(式)に(式)を くわえます add
(式)に(式)を つけくわえます append
(式)を コピーします copy
(式)が(式)で おわります endswith
(式)に(式)を まぜます extend
(式)から(式)を みつけます find
(式)を 項目でみます items
(式)で(式)を つなげます join
(式)から(式)を とりのぞきます remove
(式)から(式)を うしろからみつけます rfind
(式)を(式)で きりわけます split
(式)が(式)で はじまります startswith
(式)から 余白をとります strip
(式)を(式)で いれかえます translate
(式)を 値でみます values

 いまのところ、Orotiでは、ひとつの動詞につかえる文型はひとつだけにしています。ただ、この方法だと、似た意味の動詞をつかいたいときに、語彙的に動詞がたりなくなってきます。そういうときは、説明をおぎなうことば(随意成分)を動詞につけて、ひとつの動詞のようにしてあつかっています。

(例)

動詞 意味
みつけます まえのほうからみつける
うしろからみつけます うしろのほうからみつける

 簡約日本語の基礎語彙では、1語について3義までつかえるようにかんがえられています。Orotiの「ひとつの動詞につかえる文型はひとつだけ」という制限は、もしかしたらきつすぎるかもしれません。将来のバージョンでは変更するかもしれません。

条件分岐文

 Orotiの条件分岐文はPythonとおなじような、つぎの構造をつかいます。

(条件節)
  (主節)
  (文)
   :
   :
  (文)

 条件節のあと、字さげしてかかれたいる部分(主節とそれにつづく文)は、条件節がなりたつときだけ実行されます。ひつようがなければ、(文)の部分はなくてもかまいません。

(例)

ひとがいましたら、
  ライトのスイッチをいれます。

 条件節にはつぎの4つの基本形があります。動詞をつかうばあいと、式をつかうばあいのそれぞれについて、肯定のばあいと否定のばあいをもうけました。

(項)……(項)(V)ましたら、
(項)……(項)(V)ませんでしたら、
(式)でしたら、
(式)でないなら、

 基本の条件節は、さいごを「~ら、」という形でそろえています。

 基本形の条件節を、「そして、」や「または、」でつなげて、さらにふくざつな条件節をつくることもできます。

(例)

x<3でしたら、または、y<7でないなら、

 条件節がなりたたなかったときに実行される部分は、つぎの構造でかきます。

あるいは、(条件節)
  (主節)
  (文)
   :
   :
  (文)

 「あるいは、」ではじまる条件分岐文は、さいしょの条件分岐文につづけて、いくつでもかけます。どの条件にも一致しないときの処理は、さいごに「そうでなければ、」ではじまる条件分岐文をおいてかきます。

そうでなければ、
  (主節)
  (文)
   :
   :
  (文)

くりかえし文

 くりかえし文のかきかたは、条件分岐文がわかれば、かんたんです。条件節のあとに改行しないで、「くりかえします。」とつづけると、くりかえし文になります。

(条件節)くりかえします。
  (文)
   :
   :
  (文)

 字さげした部分の文が、条件節がなりたっているあいだくりかえし実行されます。

 無限にくりかえしつづける処理をかきたいときもあります。そういうときは、つぎのようにかきます。

真であれば、くりかえします。
  (文)
   :
   :
  (文)

 真と偽は、それぞれPythonのTrueとFalseに対応します。

 くりかえしをうちきったり、ただちに条件のチェックからやりなおしたいときは、つぎの文をつかいます。

Oroti Python
うちきります。 break
つぎへ。 continue

 リストや文字列のなかを順番に処理したいときは、つぎの形のくりかえし文がつかえます。

(式)のそれぞれの(式)について、くりかえします。
  (文)
   :
   :
  (文)

 また、文のもどり値のなかをじゅんばんに処理したいときは、つぎの形のくりかえし文がつかえます。

(項)……(項)(V)まして、それぞれの(式)について、くりかえします。
  (文)
   :
   :
  (文)

 この文型はPythonの辞書の内容を処理するときにつかえます。

(例)

辞書を項目でみまして、それぞれのなまえ、定義について、くりかえします。
    なまえ、定義をおくりだします。

Pythonの文や式のうめこみ

 Orotiは文や式の部分にPythonの文や式をかいておくこともできます。たとえば、100回なにかの処理をくりかえしたいとき、式の部分にPythonのrange関数をおいてかくこともできます。

(例)

range(100)のそれぞれのiについて、くりかえします。
  (文)
   :
   :
  (文)

※ マークダウン記法でかいている文章のなかに、HTMLのかきかたをまぜられるのと、おなじような感じです。

動詞をふやす

 Orotiでは、つかえる動詞をじぶんでふやしていくことができます。そのためには、まず、動作主体となるものを明示しておきます(主体文)。

主体: (主体名)

 つづけて、動詞の定義(文型文)をひつようなだけかいていきます。

(文型)、とは。
  (文)
   :
   :
  (文)

 動詞がつかわれると、字さげしてかいた部分の文が実行されます。このことを、Orotiでは、動詞をよびだすということがあります。

 追加する動詞は、(文型)の部分で文型といっしょに定義していきます。文型はつぎのふたつのかたちがあります。

(文型): (主体名)(助詞) (V)ます

   | (主体名)(助詞)((パラメーター))(助詞)……((パラメーター))(助詞) (V)ます

 ひとつめは、主体名以外の項がない文型です。もうひとつは、主体名の項にくわえて、パラメーターの項がひとつ以上ある文型です。文型を定義するときは、「(V)ます」のまえの一字ぶんの空白は必須です。動詞をつかうときは、動詞のまえに空白をおく必要はありません。

 パラメーターは仮引数ともいいます。かっこのなかになまえをかきます。おしえるときは、引数をうけとる箱とよく説明されているようです。たとえば、2 + 1と引数に指定してよびだされると、パラメーターのなかには3がはいっています。

 (主体名)は、動詞がよびだされたあとで実行される文の暗黙の主体になります。動詞をよびだすがわの主体ではないことに注意してください。

※ 動詞は文型がおなじであれば、複数の主体でおなじ動詞を定義してかまいません。

 例でみてみると、かんたんです。

(例)

主体: 辞書

辞書で(なまえ)から メソッドをみつけます、とは。
    辞書のメソッド集[なまえ]をメソッドにいれます。
    メソッドをかえします。

 この例では、「メソッドをみつけます」をひとつの動詞として定義しています。

 動詞をよびだしたがわに、なにかをかえしたいときは、リターン文をつかいます。

(リターン文): (式)をかえします。

 (式)がリターン文のもどり値になります。もどり値のうけとりかたは、代入文で説明したつぎの形をつかいます。

(例)

辞書で条件からメソッドをみつけまして、メソッドにいれます。

コンストラクター

 Orotiでは動詞「はじめにととのえます」は特別な動詞です。Pythonの__init__と対応するコンストラクターになります。コンストラクターは、(主体名)であらわされるものがつくられたとき自動的によびたされる動詞です。

生成文

※ 生成文は、前回までの形からかわっています。

 主体文と文型文で定義したもの(オブジェクト)をつかいたいときは、生成文をつかってオブジェクトをつくります。生成文は代入文の特殊なケースです。

あたらしい(主体名)をつくりまして、(式)にいれます。

プリント文

 文字を画面(標準出力)にかきだす機能は、Pythonでは独立した文として定義されています。Orotiでは、つぎのように動詞とprint文を対応づけています。

Oroti Python
(式)を うちだします。 print((式), end='')
(式)を おくりだします。 print((式))
おくりだします。 print()

 プリント文の動詞は、わざと、よくつかう動詞とかぶらないようにしています。ただ、タイプライターをしらないこどもには、わかりにくい動詞かもしれません。

チェック文

 プログラムをかいていると、じぶんでおもっている内容と、じっさいの動作があわないことは、しばしばあります。だいたいはプログラムのバグです。

 チェック文には、じぶんではこういうつもり、という前提条件をかいておきます。もし実行中にチェック文にかいた前提がなりたたなければ、プログラムの実行がそこでとまります。

Oroti Python
チェック: (式) assert (式)
チェック: (文) assert (文)

ライブラリ文

 Orotiでは、PythonでかかれたプログラムをOrotiからよひだすための仕かけとして、ライブラリをつかっています。

 つぎの文では、ファイル.pyとプログラム.pyの内容がトランスパイラーの出力にマージされてでてきます。

ライブラリ: ファイル、プログラム

 マージされるPythonのプログラムのなかでは、コメントのなかに主体文と文型文をかいておきます。そうすると、Orotiからもよびだすことができるようになります。また、「引数:」というコメントをかいておくと、キーワード引数としてOrotiからよびだすことができます。

ファイル.py (抜粋)

# 主体: ファイル
class ファイル:

    # ファイルを ひらきます、とは。
    # 引数: ファイル名
    def ひらきます(self, ファイル名):
        self.file = open(ファイル名)

    # ファイルを とじます、とは。
    def とじます(self):
        self.file.close()

 キーワード引数をつかうときは、動詞をよびだしたあとで、字さげしてつぎのキーワード引数文で指定します。

(キーワード引数文): (キーワード引数名)は(式)です。

(例)

ファイルをひらきます。
  ファイル名はプログラムの引数[1]です。

プログラム全体の構成

 Orotiのプログラムの実行は、

はじめに:

とかいた行のあとからはじまります。プログラム全体では、つぎのような構成になります。

(ライブラリ文)

(主体文)
-----
(動詞の定義)

(動詞の定義)

(動詞の定義)

(主体文)
-----
(動詞の定義)

(動詞の定義)

(動詞の定義)

はじめに:
-----
(文)
 :
 :
(文)

Orotiトランスパイラーの要点

 Orotiトランスパイラーの処理でとくに日本語にかかわる部分は、oroti.oro

辞書で(文字列)から メソッドをみつけます、とは。

という部分です。

 この手順では、まず文末から動詞をみつけます。このとき、文末が「うしろからみつけます」だとします。そうすると、「みつけます」と「うしろからみつけます」のように、候補となる動詞がいくつかでてきます。

 どの動詞をつかうかは、いくつかの手順でえらんでいきます。まず、文型で指定された項のならびを適用できなければ、その動詞はつかえません。それでも候補がいくつかのこれば、いちばん文字数のおおい動詞をえらぶようにしています。それでも候補がいくつかあれば、さいごにみつかった動詞をつかっています。そのような文はあいまいな文ということになります。トランスパイラーが警告をだすようにするとよいところかもしれません。

 項を助詞できりわけるときも、いくつか候補がのこることがあります。いまのところは、オペレーターとしての「の」がおおくつかえる候補を優先するようにしています。ただ、変数名に漢字やカタカナやアルファベットをつかっていれば、項のきりわけはそれほど問題にならないようです。

トランスパイラーのブートストラッピング

 いまのところ、Orotiトランスパイラーには、ふたつの実装があります。

ファイル名 説明
oroti0.py Python 3での実装
oroti.oro Orotiでの実装

 最終的には、oroti.oroでOrotiのプログラムをうごかしたいわけです。けれども、oroti.oroでoroti.oroじたいをうごかすことはできません。こうした問題はブートストラップ問題といわれたりしています。

 そこで、さいしょは、oroti0.pyでoroti.oroをPythonに変換しています。

$ ./oroti0.py oroti.oro > oroti.py

 これでoroti.oroから生成されたoroti.pyをつかえるようになります。つぎに生成されたoroti.pyをつかって、もういちどoroti.oroをPythonに変換します。

$ ./oroti.py oroti.oro > oroti.oro.py

 ねんのため、どちらのトランスパイラーをつかっても、oroti.oroから、おなじPythonのコードが生成されることを確認しています。

$ diff -s oroti.py oroti.oro.py
Files oroti.py and oroti.oro.py are identical

 GitHubにおいてあるoroti.pyが、oroti.oroから生成されたPythonのプログラムです。

まとめ

 今回は、現在のOrotiの文法と、Orotiでかいたトランスパイラーの紹介をしました。

 OritiでOtoriのトランスパイラーをかいてみるのは、なかなかおもしろい経験でした。文のあいまいさは、そのままエラーになります。わかちがきなどをつかって、はじめからどの動詞かを明示したりできるようにしておく。実装はしていませんが、そうした対処法はすぐにおもいつきます。

 けれども、Orotiはすこしちがう目的をもって、つくってみています。文があいまいだと、つたわらない。そういう部分もふくめてプログラミング体験のようにとらえています。じっさい、動詞のなまえをかんがえたりするだけでも、けっこう時間をとられます。マス形で、わかりやすい動詞をシーソラスでさがしてみたる。そうしたことが、プログラミングの一部のようになっています。

 ところで、簡約日本語の日本語はヘンな日本語。そう誤解されていることがときどきあるようです。簡約日本語はステップがすすんでいくと、最終的にはふつうの日本語とおなじになります。Orotiも、どのステップを基準にするかは、今後の検討課題のひとつです。いまのところ、OrotiはステップIIを基準に設計しています。

 簡約日本語のステップIIというのは、日本語をまなびはじめたばかりの外国のひとでもわかるくらいの日本語です。文は平明で、かんたんなコンピューターのプログラムでも解釈することができます。これくらいの日本語で、コンピューターを意図どおりにうごかすことができる。ちょっとおもしろい体験ではないかとおもいます。

 というわけで、今回はここまでです。Orotiについてコメントやアイデアなどありましたら、GitHubのIssuesまでよせてください。