6

有没有人有一个简单的例子来说明如何定义一个语法来解析使用 Jison 的块的类似 python 的缩进?

4

1 回答 1

8

我使用 Jison 创建了一种使用python-style indentation的语言。它是一种名为Bianca的自动化白盒算法测试语言。

Bianca 只有两个依赖项——一个是 Jison,另一个是Lexer。Jison 支持自定义扫描仪,Lexer 就是这样一种扫描仪。

在 C 风格的编程语言中,代码块由花括号分隔。然而,在 python 风格的缩进中,你有INDENTDEDENT标记。

在 Lexer 中编写规则来生成INDENT和标记非常简单。DEDENT事实上,Lexer 文档准确地展示了如何做到这一点。

这段代码直接取自 Bianca 的源代码 ( lexer.js ):

var indent = [0];

lexer.addRule(/^ */gm, function (lexeme) {
    var indentation = lexeme.length;

    col += indentation;

    if (indentation > indent[0]) {
        indent.unshift(indentation);
        return "INDENT";
    }

    var tokens = [];

    while (indentation < indent[0]) {
        tokens.push("DEDENT");
        indent.shift();
    }

    if (tokens.length) return tokens;
});

可以在 Python 文档中找到有关此代码如何工作的简要说明:

在读取文件的第一行之前,将一个零压入堆栈;这将永远不会再次弹出。压入堆栈的数字将始终严格从下到上递增。在每个逻辑行的开头,将行的缩进级别与堆栈的顶部进行比较。如果相等,则什么都不会发生。如果较大,则将其压入堆栈,并INDENT生成一个令牌。如果它更小,它必须是堆栈上出现的数字之一;堆栈上所有较大的数字都被弹出,并且为每个弹出的数字DEDENT生成一个令牌。在文件的末尾,DEDENT为堆栈上剩余的大于零的每个数字生成一个令牌。

于 2013-04-05T03:23:59.090 回答