Как сделать необязательное слово в 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]+