究竟如何做到这一点很难解释,因为您需要很多底层的东西(语法、AST walker、范围/符号表等)。
我写了一篇博客,解释了如何创建一种小型编程语言。如果你通读它和/或下载最后一部分的 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
控制台并打印到控制台。