Как вы сопоставляете ноль или более жетонов в Jison?

Я пишу простой синтаксический анализатор выражений в 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 токены ( звезда Клини) вместо одного или нескольких токенов ( плюс Клини). Как бы вы сделали это в 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"]
        ],

Это должно позволить любое количество новых строк до / после любого выражения.

Другие вопросы по тегам