2013-04-04 4 views
4

Я пишу простой синтаксический анализатор в 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 токенов (Kleene star) вместо одного или нескольких токенов (Kleene plus). Как вы это сделаете в Джисоне?

+1

Можете ли вы сделать производство 'newlines' включать нулевой терминал? – Barmar

+0

@ Бармар - Я могу, но я действительно не понимаю, почему я должен. По всей вероятности, вы никогда не столкнетесь с нулевым символом в обычном текстовом файле. Плюс мы не имеем дело с C-строками здесь. –

+0

Я не имел в виду нулевой символ, я имел в виду пустую постановку. – Barmar

ответ

1

Я использую Jison, и я игнорирую пробелы (включая новые линии).

Первая строка в моей% Лекс:

\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"] 
     ], 

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