【问题标题】:How do you match zero or more tokens in Jison?你如何匹配 Jison 中的零个或多个令牌?
【发布时间】:2013-04-04 04:12:30
【问题描述】:

我正在用 Jison 编写一个简单的表达式解析器,它允许任意数量的换行符跟在表达式中的二元运算符之后。到目前为止,这是我的语法:

{
    "operators": [
        ["left", "+", "-"],
        ["left", "*", "/", "%"]
    ],
    "bnf": {
        "program": [
            ["statement EOF", "return $1;"]
        ],
        "statement": [
            ["expression newlines", "$$ = $1 + ';';"]
        ],
        "expression": [
            ["NUMBER",                           "$$ = yytext;"],
            ["expression + expression",          "$$ = $1 + ' + ' + $3;"],
            ["expression - expression",          "$$ = $1 + ' - ' + $3;"],
            ["expression * expression",          "$$ = $1 + ' * ' + $3;"],
            ["expression / expression",          "$$ = $1 + ' / ' + $3;"],
            ["expression % expression",          "$$ = $1 + ' % ' + $3;"],
            ["expression + newlines expression", "$$ = $1 + ' + ' + $4;"],
            ["expression - newlines expression", "$$ = $1 + ' - ' + $4;"],
            ["expression * newlines expression", "$$ = $1 + ' * ' + $4;"],
            ["expression / newlines expression", "$$ = $1 + ' / ' + $4;"],
            ["expression % newlines expression", "$$ = $1 + ' % ' + $4;"]
        ],
        "newlines": [
            ["NEWLINE",          ""],
            ["newlines NEWLINE", ""]
        ]
    }
}

如您所见,我为每个二元运算符编写了两条规则。这在我看来是非常多余的。我宁愿有一个匹配零个或多个 NEWLINE 令牌 (Kleene star) 而不是一个或多个令牌 (Kleene plus) 的产品。你会如何在 Jison 中做到这一点?

【问题讨论】:

  • 你能否让newlines 产品包含一个空终端?
  • @Barmar - 我可以,但我真的不明白为什么我应该这样做。您很可能永远不会在常规文本文件中遇到空字符。另外,我们在这里不处理 C 字符串。
  • 我的意思不是空字符,我的意思是一个空的生产。
  • @Barmar - 不幸的是,没有。似乎 Jison 不支持空制作。我需要做更多的挖掘工作。
  • @Barmar - 糟糕,我似乎走错了路。 Jison 确实支持空产生式。我没有将产生式newlines -> NEWLINE | newlines NEWLINE 更改为newlines -> | newlines NEWLINE,而是添加了一个新产生式以形成newlines -> | NEWLINE | newlines NEWLINE。这就是造成问题的原因。您会以答案的形式写下您的评论,以便我接受吗?

标签: javascript parsing parser-generator bnf jison


【解决方案1】:

我使用 Jison,但我忽略了空格(包括换行符)。

我的 %lex 中的第一行是:

\s+   /* ignore */

但是,如果您不想这样做,则不必这样做。 尝试以下方式:

"expression": [
            ["NUMBER",                           "$$ = yytext;"],
            ["expression + expression",          "$$ = $1 + ' + ' + $3;"],
            ["expression - expression",          "$$ = $1 + ' - ' + $3;"],
            ["expression * expression",          "$$ = $1 + ' * ' + $3;"],
            ["expression / expression",          "$$ = $1 + ' / ' + $3;"],
            ["expression % expression",          "$$ = $1 + ' % ' + $3;"],
            ["expression newlines",              "$$ = $1"],
            ["newlines expression",              "$$ = $2"]
        ],

这应该允许在任何表达式之前/之后有任意数量的新行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-28
    • 1970-01-01
    • 2015-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-24
    相关资源
    最近更新 更多