0

所以我正在制作一些基本的编程语言(只是为了练习)。我使用 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

有什么想法和建议吗?谢谢!

4

1 回答 1

0

究竟如何做到这一点很难解释,因为您需要很多底层的东西(语法、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控制台并打印到控制台。

于 2012-04-10T22:08:21.413 回答