■MiniBasicの実行
1. 導出木の探索
2. ハッシュによる実現
3. Interpreterの実装
4. Mainの実装
■CAI演習課題6
■参考資料・リンク集
■質問・相談用掲示板
←目次へ戻る
2005年10月5日 6:48
更新
|
1. 導出木の探索
5章 MiniBasicの文法と解析 において、MiniBasicの文法を定義し、いくつかのプログラム例における構文解析について確認した。
ここでは、MiniBasicのプログラムの実行、すなわち、あるプログラム(命令列)に対する導出木が与えられた場合、この導出木を何らかの方法で探索し、数値演算や変数への値の代入、プログラム制御(条件実行文、繰り返し文)、ならびに組み込み関数機能の実現などを、逐次翻訳・実行するための方法について説明する。
1.1 逐次実行
1.2 条件実行文
1.1 逐次実行
文法 5.2 において、以下のプログラム例1が入力列として与えられた際、生成された導出木を図6.1に示す。この例は、変数への代入 → 変数値を5倍して表示 という2ステップを逐次実行するものである。
プログラム例1:代入と表示(乗算結果の表示)
I := 3
PRINT I * 5
図6.1: プログラム例1の導出木
ここでは、非終端記号の各ノード(Statements, Assignment, Expression, Valueなど)は、導出木内で、各々 Statements1, Statements1, Assignment1, Expression1, Expression2, ..., Value3 といった様にインスタンス名が与えられていると考えている。
4.四則演算式の実行 の場合では、各ノードでの値を評価するタイミングを検討したのだった。今回の命令列の実行では、特に各ノードでの「評価」については、[A]数値演算式の評価、[B]変数への代入、[C]組み込み関数の実施 という3つに大別される。
[A] 数値演算式の評価
図6.1 において、「値を評価すべき」タイミングは、以下の3カ所である。特に、(2)において、変数の値を評価していることに注意せよ(変数の値の取得方法については、後述)
- Value1 の葉(leaf)として、整数リテラル Number の値を評価した後、結果(整数値 3)を Value1 の結果とする。
- Value2 の葉(leaf)として、変数 Identifier:I の値を評価した後、結果(変数名 I の値)を Value2 の結果とする。
- Value3 の葉(leaf)として、整数リテラル Number の値を評価した後、結果(整数値 5)を Value3 の結果とする。
一方、図6.1 において、「数値演算を実行すべき」タイミングは、以下の2カ所である。
- Expression1 において、Value1以下の部分木の結果を得た後、これをそのまま、Expression1 以下の部分木の計算結果とする。
- Expression2 において、Value2以下の部分木の結果(left)と、Value3以下の部分木の結果(right)を得た後、これを乗算(left * right)し、結果を Expression2 以下の部分木の計算結果とする。
[B] 変数への代入
図6.1 において、「変数へ値を代入すべき」タイミングは、以下の1カ所である。
- Assignment1 の葉(leaf)として、代入する先の変数名(Identifier:I)を取得する。次に、整数値(Expression1)の値を評価した後、結果(整数値 3)を 変数名Iへの代入値としてセットする(変数へ値をセットする方法については、後述)。
[C] 組み込み関数の実施
図6.1 において、「組み込み関数を実施すべき」タイミングは、以下の1カ所である。
- PrintExp1 の葉(leaf)として、出力する整数値 Expression2 を評価する。評価した後、結果(ここでは、変数Iの値を5倍した値)を「表示」する。。
1.2 条件実行文
文法 4.2 において、以下のプログラム例2が入力列として与えられた際、生成された導出木を図6.2に示す。この例は、変数への読み込み → 変数値を絶対値変換して表示(正負の条件実行文)という2ステップを逐次実行するものである。
プログラム例2:数値読み込みと条件実行文(絶対値の表示)
READ I
IF I < 0 THEN
PRINT 0 - I
ELSE
PRINT I
ENDIF
図6.2: プログラム例2の導出木
条件実行文の命令列の実行では、条件文(論理演算式)の評価値が真か偽かによって、THEN以下の命令列を実行するか、ELSE以下の命令列を実行するかを判断する必要がある。
図6.2の場合について、具体的には、条件実行文の命令列:IfStatement1の実行では、条件文:LessThanCondition1の論理演算式の評価値が真か偽かによって、THEN以下の命令列(Statement2)を実行するか、ELSE以下の命令列(Statement3)を実行するか、という様態になっている。
特に論理演算を行うノード LessThanCondition1 での「評価」については、以下に述べる。
[D] 論理演算式の評価
図6.2:ノード LessThanCondition1 において、「値を評価すべき」タイミングは、以下の3カ所である。特に、(2)において、変数の値を評価していることに注意せよ(変数の値の取得方法については、後述)
- Value1 の葉(leaf)として、変数 Identifier:I の値を評価した後、結果(変数名 I の値)を Value1 の結果とする。
- Value2 の葉(leaf)として、整数リテラル Number の値を評価した後、結果(整数値 0)を Value2 の結果とする。
一方、図6.2:ノード LessThanCondition1 において、「論理演算の実行」タイミングは、以下の1カ所である。
- LessThanCondition1 において、Value1以下の部分木の結果(left)と、Value2以下の部分木の結果(right)を得た後、これを比較し(? left < right)し、結果(真偽値)を LessThanCondition1 以下の部分木の計算結果とする。
2. ハッシュによる実現
2.1 ハッシュ表を用いた評価値格納と変数管理
2.2 ハッシュ表を用いた評価の実際
2.1 ハッシュ表を用いた評価値格納と変数管理
MiniBasicの各ノードにおける数値/論理演算結果の格納、ならびに変数管理と代入/評価は、各々ハッシュ表を用意して行う。
ハッシュ表は、以下の2つを用意する。
・評価値管理表(values):key ノード名 --> value 整数値/論理値
・変数管理表(variables):key 変数名 --> value 数値
A. 評価値管理表(values)の操作
整数値、論理値操作向けに、各々2つの操作(書き込み/読み出し)を用意する。
整数値用
書き込み:setIntValue (引数 Node名, セットする整数値)
読み出し:getIntValue (引数 Node名) → 返り値:Nodeの評価値(整数)
論理値用
書き込み:setBoolValue (引数 Node名, セットする論理値)
読み出し:getBoolValue (引数 Node名) → 返り値:Nodeの評価値(論理値)
B. 変数管理表(variables)の操作
変数の管理/代入/評価値操作向けに、2つの操作(代入/読み出し)を用意する。
変数管理用
代入操作:setVariable (引数 変数名, セットする整数値)
読み出し:getVariable (引数 変数名) → 返り値:変数の値(整数)
※一度も代入されていない変数の評価値は、ゼロを返すようにしておく。
2.2 ハッシュ表を用いた評価の実際
プログラム例1:図6.1 の導出木において、DFS探索の各ステップにおけるハッシュ表の操作について、以下に示す。
[STEP #1] Statement1 --> Assignment1
[STEP #2] Identifier : I (変数名の取得)
[STEP #3] Token : assign ':='
[STEP #4] Value1:
setIntValue ( Value1, Number:3 )
[STEP #5] Expression1:
setIntValue ( Expression1, getIntValue ( Node1 ) )
[STEP #6] Assignment1:
setVariable ( Identifier "I", getIntValue ( Expression1 ) )
※この時点で、変数用ハッシュ表:key "I" --> value 3 が格納されている。
[STEP #7] Statement2 --> PrintExp1
[STEP #8] Token : Print 'PRINT'
[STEP #9] Value2:
setIntValue ( Value2, getVariable ( Identifier "I" ) )
[STEP#10] Token : Mult '*'
[STEP#11] Value3:
setIntValue ( Value3, Number:5 )
[STEP#12] Expression2:
left := getIntValue ( Value2 )
right := getIntValue ( Value3 )
setIntValue ( Expression2, left * right )
[STEP#13] getIntValue ( Expression2 ) --> I * 5 の値を表示
[STEP#14] Empty1 --> [EOF] 終了
3. Interpreterの実装
SableCCにて逐次翻訳・実行プログラム(インタープリター)を実装するため、まずDFS探索エンジン(DepthFirstAdapterクラス)への Visitor を実装する。
まず、探索時の各ノードの評価値ならびに変数値を管理するため、Hashtableオブジェクトを使用してハッシュ表を構成する。次に、各命令のノードについて、変数代入や各種演算、条件分岐処理、繰り返し処理などを行うためのVisitorを実装する。
Visitorは、Design Patternsの一つである。詳しくは参考文献を参照のこと。
3.1 ハッシュ表の実装
3.2 Acceptor/Visitorの例
3.3 Visitor (Interpreterクラス) の実装
3.1 ハッシュ表の実装
各ノードにおける数値/論理演算結果の格納、ならびに変数管理と代入/評価は、Hashtableオブジェクトを使用して、以下の2つを用意する。
・評価値管理表(values):key ノード名 --> value 整数値/論理値
・変数管理表(variables):key 変数名 --> value 数値
<評価値管理表(values)の実装>
// -----------------------------------------------------------------
// Hashtable to associate integer and boolean values
// with expression and condition nodes
Hashtable values = new Hashtable();
// Routines to avoid typecasts
void setIntValue(Node node, int value)
{
values.put(node, new Integer(value));
}
int getIntValue(Node node)
{
return ((Integer) values.get(node)).intValue();
}
void setBoolValue(Node node, boolean value)
{
values.put(node, new Boolean(value));
}
boolean getBoolValue(Node node)
{
return ((Boolean) values.get(node)).booleanValue();
}
|
<変数管理表(variables)の実装>
// -----------------------------------------------------------------
// Hashtable to hold variables and their values
Hashtable variables = new Hashtable();
// Routines to avoid typecasts
void setVariable(String name, int value)
{
variables.put(name.toUpperCase(), new Integer(value));
}
int getVariable(String name)
{
Integer variable = (Integer) variables.get(name.toUpperCase());
// If the variable has already been assigned a value
if(variable != null)
return variable.intValue(); // return the stored value
else
return 0; // else return 0
}
|
3.2 Acceptor/Visitorの例
DepthFirstAdapterクラスのAcceptorのうち、caseAAssignmentStatementメソッド(変数への値代入)を例にしてVisitor側の実装について検討してみる。
A. Acceptor側
caseAAssignmentStatementメソッドは、AAssignmentStatement型のnodeオブジェクトを引数とする Acceptor である。caseAAssignmentStatementメソッド(Acceptor側)の抜粋を以下に示す。
DepthFirstAdapter :: caseAAssignmentStatement の抜粋
public void caseAAssignmentStatement(AAssignmentStatement node)
{
inAAssignmentStatement(node);
if(node.getIdentifier() != null)
{
node.getIdentifier().apply(this);
}
if(node.getAssign() != null)
{
node.getAssign().apply(this);
}
if(node.getExpression() != null)
{
node.getExpression().apply(this);
}
if(node.getNewLine() != null)
{
node.getNewLine().apply(this);
}
outAAssignmentStatement(node);
}
|
これは、引数として渡された当該nodeオブジェクトについて(例えば図6.1における Assignment1 node)これの child(Identifier, Assign token, Expression) が NULL でなければ、各々のchild を探索( apply(this) )して評価する、という「探索動作のみ」を記述している。
B. Visitor側
今回は、Assignmentのchildについて、まず Expression 以下の部分木の評価値(整数値)を取得し、取得した値を、Identifier で指示されている「変数名」をキーとして、変数管理用ハッシュ表の内容を更新する、といった作業を caseAAssignmentStatement メソッドで行わせたい。
DepthFirstAdapterクラスを継承した Visitor側 Interpreter.java における、caseAAssignmentStatementメソッド(Visitor側)の抜粋を以下に示す。
Interpreter :: caseAAssignmentStatementの抜粋
public void caseAAssignmentStatement(AAssignmentStatement node)
{
node.getExpression().apply(this); // Evaluate the expression
setVariable( // Assign variable
node.getIdentifier().getText(),
getIntValue(node.getExpression()));
}
|
具体的には、ノードに到達した際、その 代入したい部分木の評価値を getExpression().apply(this) によって取得しておき、(その結果は、部分木の評価終了後、評価値管理用ハッシュ表に格納されているから)getIntValue(node.getExpression()) によってハッシュ表から取り出し、その値を、変数管理用ハッシュにおいて変数名(getIdentifier().getText())をキーにして、代入する。
3.3 Visitor (Interpreterクラス) の実装
ハッシュ表を利用して、逐次翻訳・実行動作を行うための、Visitor (Interpreterクラス) の、具体的な実装について、以下に説明する。
Interpreterクラス(ソースファイル)
InterpreterクラスのVisitor一覧
Interpreterクラス(ソースファイル)抜粋
8 package minibasic;
17 public class Interpreter extends DepthFirstAdapter
18 {
...... ハッシュの実装(3.1節参照) ........
...... Visitor : 条件実行文(IF)の実装 .........
71 /**
72 * IF condition THEN statements [ELSE statements] ENDIF
73 */
74 public void caseAIfStatement(AIfStatement node)
75 {
76 node.getCondition().apply(this); // Evaluate the condition
77
78 if(getBoolValue(node.getCondition()))
79 {
80 node.getStatements().apply(this); // Evaluate then
statements
81 }
82 else
83 {
84 node.getOptionalElse().apply(this); // Evaluate else
statements
85 }
86 }
...... Visitor : 繰り返し実行(FOR)文の実装 .........
88 /**
89 * FOR identifier := from_exp TO to_exp statements NEXT
90 */
91 public void caseAForStatement(AForStatement node)
92 {
93 node.getFromExp().apply(this); // Evaluate the from
expression
94 node.getToExp().apply(this); // Evaluate the to expression
95
96 int from = getIntValue(node.getFromExp());
97 int to = getIntValue(node.getToExp());
98
99 for(int i = from; i <= to; i++)
100 {
101 setVariable(node.getIdentifier().getText(), i);
// Assign the value to the loop variable
102
103 node.getStatements().apply(this); // Evaluate the
statements
104 }
105 }
...... Visitor : 組み込み関数(READ,PRINT)の実装 .........
110 BufferedReader in =
new BufferedReader(new InputStreamReader(System.in));
111 PrintStream out = System.out;
...... 中略 ......
120 /**
121 * READ identifier
122 */
123 public void caseAReadStatement(AReadStatement node)
124 {
125 System.out.print("? "); // Display a prompt
126 try
127 {
128 String s = in.readLine(); // Read one line of text
129 int value = Integer.parseInt(s); // parse the value
130 setVariable(node.getIdentifier().getText(), value);
// Set the variable
131 }
132 catch(IOException e) // I/O ERROR!!!
133 {
...... 例外処理(中略) ......
139 }
140 }
141
142 /**
143 * PRINT expression
144 */
145 public void caseAPrintExpStatement(APrintExpStatement node)
146 {
147 node.getExpression().apply(this); // Evaluate the expression
148
149 out.print(getIntValue(node.getExpression())); // print it
150 }
151
152 /**
153 * PRINT "string"
154 */
155 public void caseAPrintStrStatement(APrintStrStatement node)
156 {
157 String s = node.getString().getText(); // get the string text
158 out.print(s.substring(1, s.length() - 1)); // Don't print "
159 }
160
161 /**
162 * PRINTLN
163 */
164 public void caseAPrintlnStatement(APrintlnStatement node)
165 {
166 out.println(); // print a new line
167 }
...... Visitor : 変数代入文の実装 .........
172 /**
173 * ASSIGNMENT identifier := expression
174 */
175 public void caseAAssignmentStatement(AAssignmentStatement node)
176 {
177 node.getExpression().apply(this); // Evaluate the expression
178
179 setVariable( // Assign variable
180 node.getIdentifier().getText(),
181 getIntValue(node.getExpression()));
182 }
...... Visitor : 条件文(論理式)の評価 .........
187 static final int LT = 0;
188 static final int GT = 1;
189 static final int EQ = 2;
190
191 boolean evalCondition(Node left, Node right, int operator)
192 {
193 left.apply(this); // Evaluate the left expression
194 right.apply(this); // Evaluate the right expression
195
196 switch(operator)
197 {
198 case LT: return getIntValue(left) < getIntValue(right);
199 case GT: return getIntValue(left) > getIntValue(right);
200 case EQ: return getIntValue(left) == getIntValue(right);
201 default: throw new RuntimeException("Internal Error");
202 }
203 }
204
205 /**
206 * CONDITION(LT) left < right
207 */
208 public void caseALessThanCondition(ALessThanCondition node)
209 {
210 setBoolValue(node, evalCondition(node.getLeft(),
node.getRight(), LT));
211 }
212
213 /**
214 * CONDITION(GT) left > right
215 */
216 public void caseAGreaterThanCondition(AGreaterThanCondition node)
217 {
218 setBoolValue(node, evalCondition(node.getLeft(),
node.getRight(), GT));
219 }
220
221 /**
222 * CONDITION(EQ) left = right
223 */
224 public void caseAEqualCondition(AEqualCondition node)
225 {
226 setBoolValue(node, evalCondition(node.getLeft(),
node.getRight(), EQ));
227 }
...... Visitor : 数値演算式の評価 .........
232 static final int PLUS = 0;
233 static final int MINUS = 1;
234 static final int MULT = 2;
235 static final int DIV = 3;
236 static final int MOD = 4;
237
238 int evalExpression(Node left, Node right, int operator)
239 {
240 left.apply(this); // Evaluate the left expression
241 right.apply(this); // Evaluate the right expression
242
243 switch(operator)
244 {
245 case PLUS: return getIntValue(left) + getIntValue(right);
246 case MINUS: return getIntValue(left) - getIntValue(right);
247 case MULT: return getIntValue(left) * getIntValue(right);
248 case DIV: return getIntValue(left) / getIntValue(right);
249 case MOD: return getIntValue(left) % getIntValue(right);
250 default: throw new RuntimeException("Internal Error");
251 }
252 }
253
254 /**
255 * GET value
256 */
257 public void caseAValueExpression(AValueExpression node)
258 {
259 node.getValue().apply(this); // Evaluate the expression
260
261 setIntValue(node, getIntValue(node.getValue()));
262 }
263
264 /**
265 * CALC(PLUS) left + right
266 */
267 public void caseAPlusExpression(APlusExpression node)
268 {
269 setIntValue(node, evalExpression(node.getLeft(),
node.getRight(), PLUS));
270 }
271
272 /**
273 * CALC(MINUS) left - right
274 */
275 public void caseAMinusExpression(AMinusExpression node)
276 {
277 setIntValue(node, evalExpression(node.getLeft(),
node.getRight(), MINUS));
278 }
279
280 /**
281 * CALC(MULT) left * right
282 */
283 public void caseAMultExpression(AMultExpression node)
284 {
285 setIntValue(node, evalExpression(node.getLeft(),
node.getRight(), MULT));
286 }
287
288 /**
289 * CALC(DIV) left / right
290 */
291 public void caseADivExpression(ADivExpression node)
292 {
293 try
294 {
295 setIntValue(node, evalExpression(node.getLeft(),
node.getRight(), DIV));
296 }
297 catch(ArithmeticException e) // DIVIDE BY ZERO ERROR
298 {
299 error("DIVIDE BY ZERO ERROR IN LINE " +
node.getDiv().getLine());
300 }
301 }
302
303 /**
304 * CALC(MOD) left MOD right
305 */
306 public void caseAModExpression(AModExpression node)
307 {
308 try
309 {
310 setIntValue(node, evalExpression(node.getLeft(),
node.getRight(), MOD));
311 }
312 catch(ArithmeticException e) // MODULUS ZERO ERROR
313 {
314 error("MODULUS ZERO ERROR IN LINE " +
node.getMod().getLine());
315 }
316 }
...... Visitor : リテラル、変数値の取得 .........
321 /**
322 * CONTSTANT value (integer format)
323 */
324 public void caseAConstantValue(AConstantValue node)
325 {
326 try
327 {
328 int value = Integer.parseInt(node.getNumber().getText());
329 setIntValue(node, value);
330 }
331 catch(NumberFormatException e) // NUMBER FORMAT ERROR!!!
332 {
333 error("NUMBER FORMAT ERROR IN LINE " +
node.getNumber().getLine());
334 }
335 }
336
337 /**
338 * IDENT value (assigned variable)
339 */
340 public void caseAIdentifierValue(AIdentifierValue node)
341 {
342 setIntValue(node, getVariable(node.getIdentifier().getText()));
343 }
344
345 /**
346 * EXPRESSION value
347 */
348 public void caseAExpressionValue(AExpressionValue node)
349 {
350 node.getExpression().apply(this); // Evaluate the expression
351
352 setIntValue(node, getIntValue(node.getExpression()));
353 }
357 }
|
<説明>
17行目:Interpreterクラス宣言(DepthFirstAdapterクラスから継承)
71--86行目:条件実行文の実装
構文規則 IF condition THEN statements [ELSE statements] ENDIF に対応する、caseAIfStatement Visitor の実装である。
・論理式Conditionを評価(getCondition())
・評価値管理ハッシュを表引き
評価値が真の場合 --> THEN以下Statement部分木を探索
評価値が偽の場合 --> ELSE以下OptionalElse部分木を探索
88--105行目:繰り返し実行文の実装
構文規則 FOR identifier := from_exp TO to_exp statements NEXT に対応する、caseAForStatement Visitor の実装である。
・カウント用変数の開始値 FromExpを評価(getFromExp())--> from
・カウント用変数の終了値 ToExpを評価(getToExp())--> to
・from から to までの回数分、以下を繰り返し実行する
カウント用変数について、現在のカウント値を代入
Statements部分木を探索
110--167行目:組み込み関数(READ,PRINT,PRINTLN)の実装
標準入力からの読み込み、ならびに標準出力への表示についての実装である。
172--182行目:変数代入文の実装
3.2節 B.を参照のこと
187--227行目:論理演算式の評価の実装
IF条件実行文で用いられる論理式の評価についての実装である。
・leaf left を評価
・leaf right を評価
・evalCondition関数を用いて、left : right の関係の真偽を評価
・評価値管理ハッシュへ、当該ノードの評価値(論理値)をセット
232--316行目:数値演算式の評価の実装
・leaf left を評価
・leaf right を評価
・evalExpression関数を用いて、left ↑ right の演算を評価
・評価値管理ハッシュへ、当該ノードの評価値(整数値)をセット
321--353行目:リテラル・変数値の取得の実装
4. Mainの実装
SableCCにおいて、文法ファイルに基づいて生成された lexer/parser, ならびに先に実装した Visitor(Interpreterクラス)を駆動するため、Mainを実装する。最後に、実行プログラム全体をビルドし、入力命令列を与えてテストを行う。
4.1 Main.javaの実装
4.2 実行プログラムのビルドとテスト
4.1 Main.javaの実装
Lexer, Parser, 各ノードオブジェクト(node)のクラスパッケージを利用し、Visitor(Interpreterクラス)を利用してプログラム実行動作を駆動するための、Mainの具体的な実装について、以下に説明する。
Mainクラス(ソースファイル)
Mainクラスの実装(抜粋)
8 package minibasic;
11 import minibasic.node.*;
12 import minibasic.lexer.*;
13 import minibasic.parser.*;
17 public class Main
18 {
19 public static void main(String[] arguments)
20 {
21
22 try
23 {
24 Lexer l = new Lexer(
25 new PushbackReader(
26 new BufferedReader(
27 new FileReader(arguments[0])), 1024));
28
29 Parser p = new Parser(l);
30
31 Node tree = p.parse();
32
33 tree.apply(new Interpreter());
34 }
35 catch(Exception e)
36 {
37 System.out.println(e);
38 }
39 }
40 }
|
<説明>
11-13行目
node, lexer, parserクラスパッケージの利用を宣言
24--27行目
ファイル入力ストリームから PushbackReader を使用して入力列を読み込み、Lexerコンストラクタによって字句解析器 Lexerオブジェクトのインスタンス l を得る。
29行目
Lexerのインスタンス l を引数として、Parserコンストラクタによって構文解析器 Parserオブジェクトのインスタンス p を得る。
31行目
Parserクラスの parseメソッドによって、導出木のインスタンス tree を得る。
33行目
Visitorクラスの Interpreter のインスタンス を new し、導出木treeに対してDFS探索を実行する。
4.2 実行プログラムのビルドとテスト
minibasicプロジェクトファイルはここからダウンロード
minibasic-src.tar.gz
実際に、MiniBasicプログラムのいくつかを、インタープリター実行プログラム(minibasic.jar)に入力した場合の実行結果を以下に示す。
<プログラム例1 test2.basic(絶対値の表示)>
PRINT "What is your number"
READ I
PRINT "ABS( "
PRINT I
PRINT " ) = "
IF I < 0 THEN
PRINT ( 0 - I )
ELSE
PRINT I
ENDIF
PRINTLN
<実行結果1:プログラム例1 test2.basic>
$ java -jar minibasic.jar test2.basic
What is your number? 9
ABS( 9 ) = 9
$ java -jar minibasic.jar test2.basic
What is your number? -9
ABS( -9 ) = 9
|
<プログラム例2 test3.basic(かけ算の表)>
PRINT "What is your number"
READ I
FOR X := 1 TO I
FOR Y := 1 TO I
PRINT X * Y
PRINT " "
NEXT
PRINTLN
NEXT
PRINTLN
<実行結果2:プログラム例2 test3.basic>
$ java -jar minibasic.jar test3.basic
What is your number? 9
1 2 3 4 5 6 7 8 9
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81
$ java -jar minibasic.jar test3.basic
What is your number? 16
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32
3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48
4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64
5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80
6 12 18 24 30 36 42 48 54 60 66 72 78 84 90 96
7 14 21 28 35 42 49 56 63 70 77 84 91 98 105 112
8 16 24 32 40 48 56 64 72 80 88 96 104 112 120 128
9 18 27 36 45 54 63 72 81 90 99 108 117 126 135 144
10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160
11 22 33 44 55 66 77 88 99 110 121 132 143 154 165 176
12 24 36 48 60 72 84 96 108 120 132 144 156 168 180 192
13 26 39 52 65 78 91 104 117 130 143 156 169 182 195 208
14 28 42 56 70 84 98 112 126 140 154 168 182 196 210 224
15 30 45 60 75 90 105 120 135 150 165 180 195 210 225 240
16 32 48 64 80 96 112 128 144 160 176 192 208 224 240 256
|
<プログラム例3 test4.basic(Newton法による二乗根)>
PRINT "What is your number"
READ I
X := 3
FOR N := 1 TO 20
X := ( X + ( ( I * 10000 ) / X ) ) / 2
PRINT "N="
PRINT N
PRINT ", X="
PRINT X
PRINTLN
NEXT
PRINT "SQRT ( "
PRINT I
PRINT " ) = "
PRINT ( X / 100 )
PRINT "."
PRINT ( X % 100 )
PRINTLN
<実行結果3:プログラム例3 test4.basic>
$ java -jar minibasic.jar test4.basic
What is your number? 3
N=1, X=5001
N=2, X=2503
N=3, X=1257
N=4, X=640
N=5, X=343
N=6, X=215
N=7, X=177
N=8, X=173
N=9, X=173
N=10, X=173
N=11, X=173
N=12, X=173
N=13, X=173
N=14, X=173
N=15, X=173
N=16, X=173
N=17, X=173
N=18, X=173
N=19, X=173
N=20, X=173
SQRT ( 3 ) = 1.73
$ java -jar minibasic.jar test4.basic
What is your number? 4096
N=1, X=6826668
N=2, X=3413336
N=3, X=1706673
N=4, X=853348
N=5, X=426697
N=6, X=213396
N=7, X=106793
N=8, X=53588
N=9, X=27176
N=10, X=14341
N=11, X=8598
N=12, X=6680
N=13, X=6405
N=14, X=6400
N=15, X=6400
N=16, X=6400
N=17, X=6400
N=18, X=6400
N=19, X=6400
N=20, X=6400
SQRT ( 4096 ) = 64.0
|
|