最近の更新 (Recent Changes)

2014-01-01
2013-01-04
2012-12-22
2012-12-15
2012-12-09

Wikiガイド(Guide)

サイドバー (Side Bar)


← 前のページに戻る

9. 七式言語: Javascriptに変換されるプログラミング言語

9.1 Javascriptに変換されるプログラミング言語

さて、ここまでの六式言語までは、コンパイル結果をC言語として出力して行ってきました。

しかし、C言語に限る必要はありません。JAVAでもGo言語でもアセンブラでももちろん構いません。

そこで、ここからはJavascriptに変換する言語について説明しましょう。

Javascriptは、Webブラウザ上で使われることの多い特別な言語です。 しかし、言語の構文としてはC言語とJavascriptはそんなに大きくは変わりません。

ここで作成する七式言語ではPL/0言語を、C言語とJavascriptの共通する部分はそのまま使い、異なる部分を変更することにより実現します。

例えば、次のようなC言語のプログラムを見てください。


#include <stdio.h>
#include <stdlib.h>

int main()
{
   int x, y;

   x = 1;
   y = 2;

   printf("%d", x+y);
   printf("\n");
}

これは、Javascriptに書き換えると一例として次のようになります。


   var x, y;

   x = 1;
   y = 2;

   document.write(x+y);
   document.write("<br>");

#include や main関数とか不要なのですっきりとしていますが、プログラムの要素は変わっていません。

これをブラウザ上で実行しやすいように次のように前後にHTMLのタグをつけてみましょう。


<HTML>
<HEAD>
<TITLE>PL/0 to javascript</TITLE>
</HEAD>
<BODY>
<SCRIPT type="text/javascript">
<!--

   var x, y;

   x = 1;
   y = 2;

   document.write(x+y);
   document.write("<br>");

// -->
</SCRIPT>
</BODY>
</HTML>

<!-- の次の行から // --> の前の行までがJavascriptの部分です。

これをa.htmlと名前をつけて保存してください。 このファイルをダブルクリックしたり、ブラウザで読み込んで実行してください。

3と表示されたでしょうか?

9.2 七式言語の改造点

9.2.1 いかに実現するか?

C言語を出力するPL/0言語で構文は変えずに、Javascriptを出力するように改造しましょう。

予想よりも簡単に対応できてしまいます。

改造による変更は大きく分けると、データ型の変更、文字列の出力関数の変更、およびHTMLタグの追加を行います。

データ型の変更は次のようになります。

まず、PL/0のconstで定義される型は次のように変更されます。


C言語
定数型定義 const int

↓
Javascript
定数型定義 var

Javascriptには、共通の規格としての定数の定義がないので、とりあえずvarで型定義するようにします。 本来ならば、代入文の左辺に現れないように意味解析時にチェックすれば定数として充分よいのですが、今回は特に対応しません。 (後の章で対応した新言語を紹介する予定です)

次にPL/0のvarで定義される整数データ型は次のように変更されます。


C言語
整数型定義 int

↓
Javascript
整数型定義 var

Javascriptだからvar型にすればどんな型でも使えるので、整数データ型として使っても大丈夫です。

次にPL/0の手続き定義の型は次のように変更されます。


C言語
手続き定義 void 手続き名()

↓
Javascript
手続き定義 function 手続き名()

これだけでデータ型の変更は終わりです。

次は、文字列の出力関数の変更です。


C言語
printf("%d", データ)

↓
Javascript
document.write(データ)

document.write()を使うとWeb上の画面に自由にデータ出力を表示することができます。

最後に、次のようにHTMLタグをJavascriptの出力の前後に付けるようにPL/0を改造します。


<HTML>
<HEAD>
<TITLE>PL/0 to javascript</TITLE>
</HEAD>
<BODY>
<SCRIPT type="text/javascript">
<!--

Javascriptの出力

// -->
</SCRIPT>
</BODY>
</HTML>


さて、これで準備OKです。次の項ではソースを示しましょう。

9.3 七式言語のソース

元のC言語出力のPL/0からの変更部分はソース上に注釈行で入れてみましょう。


// Compiler of PL/0 by descartes (translator)

<program>
                                <setVar Line 1>
                // ここからhtml形式になるようにHTMLタグを出力させます。
                                <print '<HTML>'>
                                <print "<HEAD>">
                                <print "<TITLE>PL/0 to javascript</TITLE>">
                                <print "</HEAD>">
                                <print "<BODY>">
                                <print '<SCRIPT type="text/javascript">'>
                                <print "<!--">

                // ここからは、PL/0ソースの解析とコンパイル結果の出力
                <block>         <emsg "'.' is missing.">
                "."

                // ここからはHTMLタグの後半を出力
                                <print "// -->">
                                <print "</SCRIPT>">
                                <print "</BODY>">
                                <print "</HTML>">
                ;
<block>         [ "const"       <emsg "constant name.">
                                <printf "var ">  // const型はvarに変換
                  <ident>       <emsg "constant definition.">
                  "="           <printf " = ">
                  <number>
                  {","          <printf ", ">
                   <ident>      <emsg "constant definition.">
                   "="          <printf " = ">
                   <number>
                   }            <emsg "';' is missing.">
                   ";"          <print ";">
                ]
                [ "var"         <emsg "variable name.">
                                <printf "var ">  // var型はvarのまま
                  <ident>       <emsg "variable definition.">
                  {","          <printf ", ">
                   <ident>      <emsg "variable definition.">
                   } ";"        <print ";">
                ]
                { "procedure"   <emsg "procedure name.">
                                <printf "function ">  // procedure手続き型はfunction型に変換
                  <ident>       <emsg "procedure definition.">
                                <print "()">
                  ";"
                                <print "{">
                  <block> ";"   <print "}">
                }
                <statement>
                ;
<statement>     <SKIPSPACE> ::sys <line #Line> <setVar Line #Line>
                [
                  <ident>
                  (":=" | "=")
                                <emsg "expression.">
                                <printf " = ">
                  <expression>  <print ";">
                | "call"        <emsg "procedure.">
                  <ident> <print "();">
                | "begin"       <print "{">
                     <statement> {";" <statement>}
                  "end"         <print "}">
                | "if"          <emsg "if sentence.">
                   <printf "if (">
                   <condition>
                   "then"       <print ") ">
                   <statement>
                | "while"       <emsg "while sentence.">
                                <printf "while (">
                  <condition>
                  "do"          <print ")">
                  <statement>
                |
                  "print"       <emsg "print sentence. ">
                   [
                    // print出力はdocument.write()を出力して使う。
                    (
                      <ident #id>       <print 'document.write(' #id ');'>
                    | <number #s #n>    <print 'document.write(' #s #n ');'><print>
                    | <strings #str>    <print 'document.write("' #str '");'><print>
                    )
                   { ","
                    (
                      <ident #id2>      <print 'document.write(' #id2 ');'>
                    | <number #s2 #n2>  <print 'document.write(' #s2 #n2 ');'><print>
                    | <strings #str2>   <print 'document.write("' #str2 '");'><print>
                    )
                   }
                   ]
                ];
<condition>     "odd"           <emsg "odd syntax.">
                                <printf "((">
                  <expression>  <printf ") & 1)">
                |
                <expression>
                ("="            <printf " == ">
                |"#"            <printf " != ">
                |"<="           <printf " <= ">
                |"<"            <printf " < ">
                |">="           <printf " >= ">
                |">"            <printf " > ">
                )
                <expression> ;
<expression>    [ "+"           <printf "+">
                 |"-"           <printf "-">
                ] <term> {
                        ("+"    <printf "+">
                        |"-"    <printf "-">
                        ) <term>};
<term>          <factor> {
                ("*"            <printf "*">
                |"/"            <printf "/">
                ) <factor>};
<factor>        <ident> | <number>
                | "("           <printf "(">
                        <expression>
                  ")"           <printf ")">
                ;

<ident #id>     <ID #id>
                <reserved #id>
                ;
<ident>         <ident #id>
                <printf #id>
                ;
<number #sign #n>
                ["+"            <is #sign "">
                |
                 "-"            <is #sign "-">
                |
                                <is #sign "">
                ]
                <NUM #n>
                ;
<number>        <number #sign #n>
                <printf #sign #n>
                ;
<strings #str>  <STRINGS #str>
                ;
<strings>       <strings #str>
                <printf #str>
                ;

<reserved #id>
                <not ::sys <member #id
                  (var procedure begin end if then while do call print odd)>>
        ;

<emsg #x>
                <x <getVar #Line Line>
                   <warn "error : " #Line ":" #x>
                   <exit>>
                ;

<compile>
        ::sys<args #x>
        ::sys<nth #inputfile #x 1>
        ::sys<suffix #outputfile #inputfile html>  // 出力ファイルの拡張子を.htmlにする
        <print inputfile #inputfile>
        <print outputfile #outputfile>
        ::sys<openw #outputfile
                ::sys<openr #inputfile <program>>>
        ;

? <compile>;




9.4 七式言語のソースのコンパイル方法

それでは、七式言語用のサンプルプログラムを作成してコンパイルしてみましょう。

まず、「9.3 七式言語のソース」を pl0.dec と名前をつけて保存しておいてください。

次のサンプルプログラムのソースを使います。


const MAX=1000;
var i;
procedure loop;
begin
        while i < MAX do
        begin
                print i, "<br>";
                i := i+1
        end;
end;

begin
        i := 0;
        call loop
end.

PL/0言語そのままの構文です。

0から999までの数を改行しながら、Webブラウザに出力します。

print文の出力で改行するのに"<br>"とhtmlのタグを出力しているところが、特徴的ですね。

このサンプルプログラムをtest.pl0という名前で保存してコンパイルします。


$ descartes pl0.dec test.pl0
inputfile test.pl0
outputfile test.html
result --
        <compile>
-- true

test.html にコンパイル結果が出力されました。

インデントを直してtest.htmlを見ると次のようになります。


<HTML>
<HEAD>
<TITLE>PL/0 to javascript</TITLE>
</HEAD>
<BODY>
<SCRIPT type="text/javascript">
<!--
var MAX = 1000;
var i;
function loop()
{
  {
    while (i < MAX)
    {
      document.write( i );
      document.write(" <br> ");

      i = i+1;
    }
  }
}
{
  i = 0;
  loop();
}
// -->
</SCRIPT>
</BODY>
</HTML>

HTMLのファイルの中に、Javascriptのプログラムが埋め込まれているのがわかります。

作成されたtest.htmlを実行すると0から999までの数が、ブラウザの中に表示されます。


js01.jpg