Как сделать необязательное слово в PEG.js

Я пытаюсь создать простой парсер с PEG.js. Я хочу, чтобы пользователь мог вводить ряд ключевых слов с необязательным "И" между ними, но я не могу получить необязательные и работающие. Он всегда этого ожидает, хотя я пометил это? (ноль или один).

Вставьте эту грамматику в http://pegjs.majda.cz/online:

parse = pair+

pair = p:word and? { return p }

word = w:char+ { return w.join(""); }

char = c:[^ \r\n\t] { return c; }

and = ws* 'and'i ws*

ws = [ \t]

Моя цель состоит в том, чтобы любой из этих входных данных был разобран в массив ["foo", "bar"]:

foo bar
foo and bar

3 ответа

Ок, неважно Я понял. Это было потому, что я сделал необязательный пробел перед 'и' как часть правила and, поэтому он ожидал остальную часть правила. Мне просто нужно было перенести это в правило пар, вот так:

parse = pair+
pair  = p:word ws* and? { return p }
word  = w:char+ { return w.join(""); }
char  = c:[^ \r\n\t] { return c; }
and   = 'and'i ws*
ws    = [ \t]

Я знаю, что это очень старый вопрос, но, видя, что на него не было ответа, и кто-то может наткнуться на него, я хотел бы представить свой ответ:

Program
    = w1:$Word _ wds:(_ "and"? _ w:$Word { return w; })* _  {
        wds.unshift(w1);
        return wds;
    }
Word 
    = [a-zA-Z]+
 _
    = [ ,\t]*

"И" является необязательным, и вы можете добавить столько слов, сколько хотите. Парсер пропустит "и" и возвратит список слов. Я взял на себя смелость удаления запятых.

Вы можете попробовать это https://pegjs.org/online с такой строкой:

carlos, peter, vincent, thomas, and shirly

Надеюсь, это поможет кому-то.

Вот мой ответ:

start
  = words

words
  = head:word tail:(and (word))* {
    var words = [head];
    tail.forEach(function (word) {
      word = word[1];
      words.push(word);
    })
    return words;
  }

and
  = ' and '
  / $' '+

word
  = $chars

chars 'chars'
  = [a-zA-Z0-9]+
Другие вопросы по тегам