多くの基礎となるもの(文法、ASTウォーカー、スコープ/シンボルテーブルなど)が必要なため、これを正確に行う方法を説明するのは困難です。
小さなプログラミング言語を作成する方法を説明するブログを書きました。それを読んだり、最後の部分のzipをダウンロードしたりする場合は、ユーザー入力をサポートするためにいくつか追加するだけで済みます。これらはあなたがする必要がある変更です:
ファイルTL.g:
atom
: Number
| Bool
| Null
| lookup
| Input '(' String? ')' -> ^(Input String?) // added this line
;
Input : 'input'; // added this rule
ファイルTLTreeWalker.g:
expression returns [TLNode node]
: ^(TERNARY a=expression b=expression c=expression) {node = new TernaryNode($a.node, $b.node, $c.node);}
| ^(In a=expression b=expression) {node = new InNode($a.node, $b.node);}
| ^('||' a=expression b=expression) {node = new OrNode($a.node, $b.node);}
| ^('&&' a=expression b=expression) {node = new AndNode($a.node, $b.node);}
| ^('==' a=expression b=expression) {node = new EqualsNode($a.node, $b.node);}
| ^('!=' a=expression b=expression) {node = new NotEqualsNode($a.node, $b.node);}
| ^('>=' a=expression b=expression) {node = new GTEqualsNode($a.node, $b.node);}
| ^('<=' a=expression b=expression) {node = new LTEqualsNode($a.node, $b.node);}
| ^('>' a=expression b=expression) {node = new GTNode($a.node, $b.node);}
| ^('<' a=expression b=expression) {node = new LTNode($a.node, $b.node);}
| ^('+' a=expression b=expression) {node = new AddNode($a.node, $b.node);}
| ^('-' a=expression b=expression) {node = new SubNode($a.node, $b.node);}
| ^('*' a=expression b=expression) {node = new MulNode($a.node, $b.node);}
| ^('/' a=expression b=expression) {node = new DivNode($a.node, $b.node);}
| ^('%' a=expression b=expression) {node = new ModNode($a.node, $b.node);}
| ^('^' a=expression b=expression) {node = new PowNode($a.node, $b.node);}
| ^(UNARY_MIN a=expression) {node = new UnaryMinusNode($a.node);}
| ^(NEGATE a=expression) {node = new NegateNode($a.node);}
| Number {node = new AtomNode(Double.parseDouble($Number.text));}
| Bool {node = new AtomNode(Boolean.parseBoolean($Bool.text));}
| Null {node = new AtomNode(null);}
| lookup {node = $lookup.node;}
| ^(Input String?) {node = new InputNode($String.text);} // added this line
;
次のクラスを追加します。
package tl.tree.functions;
import tl.TLValue;
import tl.tree.TLNode;
import java.io.PrintStream;
import java.util.Scanner;
public class InputNode implements TLNode {
private String prompt;
private PrintStream out;
public InputNode(String p) {
this(p, System.out);
}
public InputNode(String p, PrintStream o) {
prompt = (p == null) ? "" : p;
out = o;
}
@Override
public TLValue evaluate() {
out.println(prompt);
Scanner keyboard = new Scanner(System.in);
if(keyboard.hasNextDouble())
return new TLValue(Double.valueOf(keyboard.nextDouble()));
else if(keyboard.hasNextInt())
return new TLValue(Integer.valueOf(keyboard.nextInt()));
else if(keyboard.hasNextBoolean())
return new TLValue(Boolean.valueOf(keyboard.nextBoolean()));
else
return new TLValue(keyboard.nextLine().trim()); // else it's a plain string
}
}
そして、ここで入力を評価すると、次のようになります。
a = 10;
b = input("Enter a number: ");
println(a + b);
メッセージのプロンプトが表示されEnter a number:
、この番号がコンソールに追加a
されてコンソールに出力されます。