所以我正在制作一些基本的编程语言(仅用于练习)。我用ANTLR制作了简单的语法。
让我们用它作为简单程序的例子。
begin
int a;
a = 3+4*4;
end
让我们测试一下是否运行以下java类。
public class Test {
public static void main(String[] args) throws RecognitionException {
CharStream charStream = new ANTLRStringStream("here goes the code");
LangLexer lexer = new LangLexer(charStream);
TokenStream tokeStream = new CommonTokenStream(lexer);
LangParser parser = new LangParser(tokeStream);
Lang.program();
System.out.println("done");
}
}
现在我被卡住了。我想制作,例如“输入x”和“打印x”。因此,当您在代码中输入“x”时,程序会要求您输入一些数字,并将给定值存储在var X中。而使用print X,它会在控制台中输出该值。
begin
int a, b, c;
input a;
input b;
c = a + b;
print c;
end
有什么想法和建议吗? 谢谢!
答案 0 :(得分:0)
如何做到这一点很难解释,因为你需要很多底层的东西(语法,AST walker,范围/符号表等)。
我写过a blog that explains how to create a small programming language。如果您通读它和/或下载最后一部分的zip,您只需要添加一些东西来支持用户输入。这些是您需要做出的更改:
atom
: Number
| Bool
| Null
| lookup
| Input '(' String? ')' -> ^(Input String?) // added this line
;
Input : 'input'; // added this rule
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
并打印到控制台。