首页 文章

如何为小语言 Build 翻译? [关闭]

提问于
浏览
3

我想弄清楚从这个项目开始的位置 . 也许有人可以引导我朝着正确的方向前进 .

给我一个小语言,我必须为他写一个翻译 . 该语言由括号中的表达式组成:

(integer integer operator)

或由以下形式的表达式组成的算术IF语句:

IF exp1 exp2 exp3 exp4

如果exp1为负,则返回exp2,如果exp1为零,则返回exp3;如果exp1为正,则返回exp4 .

运算符是或者x(分别用于加法和乘法) .

我必须一起实现一个扫描器/解析器,然后是将输出结果的解释器 . 解释器部分并不困难,但我无法弄清楚如何开始扫描/解析过程 .

我已经开始使用Java,并让Scanner对象收集输入并将其存储在字符串中 . 然后我将String拆分为一个String数组,不使用任何作为分隔符(这样每个单个字符,符号,空格等都存储在它自己的字符串索引中) . 这可能不是最好的方法,因为我无法弄清楚从哪里开始 . 我无法理解的部分是如果不遵循这种语法,如何返回错误,或者如何检测括号和/或IF等 .

这是我在上一段中描述的代码片段:

public void run() {
    Scanner sc = new Scanner(System.in);

    while (sc.hasNext()) {
        String sLine = sc.nextLine();
        String[] scanned = sLine.split("");

输入示例:

(7 2 +)

Output: 9

IF (2 -2 +) (5 2 +) (5 -2 x) (5 2 x)

Output: -10

如果有人对我有好的指示,请分享 . :)

4 回答

  • 1

    您可以使用基于堆栈的算法来处理后缀表达式 . 一个简单的想法是将整数推入堆栈,当遇到运算符时,从堆栈中弹出整数并执行运算符提到的操作,如, - .

  • 3

    我建议你使用C和boost精神库....

  • 0

    我认为使用ANTLR,JavaCC,SampleCC或其他解析器生成器工具将使用大锤来破解坚果 . 如果语法定义中没有递归,只需要几个方法就足够了 . 下面的代码给出了一个基本的想法(它可能无法编译或工作,我从头开始编写它作为插图如何开始):

    public int parse(String input) {
    Scanner scanner = new Scanner(input);
    
        return consumeLine(scanner);
    }
    
    public int consumeLine(Scanner scanner) {
        if( scanner.hasNext("(") ) {
            return consumeExpression(scanner);
    
        } else if( scanner.hasNext("IF") ) {
            return consumeIf(scanner);
        }
    }
    
    
    public int consumeExpression(Scanner scanner) {
        scanner.next("(");
        int a = scanner.nextInt();
        int b = scanner.nextInt();
        String op = scanner.next("[+-/*]");
        scanner.next(")");
    
        if( "+".equals(op) ) {
            return a + b;
    
        } else if( "-".equals(op) ) {
            return a - b;
        } ...
    
        throw new RuntimeException("parsing error");
    }
    
    public int consumeIf(Scanner scanner) {
        scanner.next("IF");
        int exp1 = consumeExpression(scanner);
        int exp2 = consumeExpression(scanner);
        int exp3 = consumeExpression(scanner);
        int exp4 = consumeExpression(scanner);
    
        if( exp1 < 0 ) {
            return exp2;
        } else if( exp1 == 0 ) {
            return exp3;
        } ...
    
        throw new RuntimeException("should not be here (TM)");
    }
    
  • 2

    如果你是java的话,使用javacc很容易 . 您可以通过紧凑而简单的方式提及令牌以及如何处理它们,然后在编译时它会生成执行逻辑所需的java源代码中的所有代码 .

    javacc intro

    javacc faq

相关问题