Я пытаюсь создать DSL с помощью peg js. Прямо сейчас мой парсер анализирует разного рода вопросы на основе разных символов. Теперь мне нужно проанализировать необработанный текст и получить заданный c вывод:
тип: raw, content: text.
Пока этот текст анализируется правильно, но если текст отсутствует, мои другие типы вопросов не анализируются и выдают следующую ошибку:
Ожидаемый конец ввода или необработанный тип, но найдено "&". Мне нужно сделать необработанный текст необязательным, чтобы при обнаружении синтаксический анализатор анализировал его, как я определил, но когда не нужно пропускать и анализировать следующие типы вопросов. Моя грамматика следующая:
{
function makeInteger(o) {
return parseInt(o.join(""),10);
}
function createQuestion(id, title, type, options, placeholder, labels, required, min,
max, ml, hf, ht, hs) {
var question = {
id: id,
title: title,
//content: content,
type: type,
options: options,
placeholder: placeholder,
labels: labels,
required: required,
min: min,
max: max,
maxlength: ml,
hours_from: hf,
hours_to: ht,
hours_step: hs
}
return question;
}
function createContentQuest(QuestionId,content){
if(QuestionId != null)
return content
}
function removeDuplicateSpaces(text) {
return text.replace(/\s\s+/g,'');
}
function removebrackets(RichText) {
return text.replace();
}
}
content
= content:Raw? {createContentQuest(); return content}
Raw 'rawtype'
= content:RichText questions:(Question)* {return{type:"raw",content, questions}}
Questions
= _ questions:(Question)* _ { return questions }
Question '(question)'
= QuestionAnswersAtEnd
QuestionAnswersAtEnd "(question with answers at end)"
= id:QuestionId _ title:QuestionTitle _ type:QuestionType? _ options:QuestionOptions? _
placeholder:QuestionPh? _ labels:Questionlab? _ required:Questionreq? _ min:Questionmin?
_ max:Questionmax? _ ml:Questionmaxlength? _ hf:QuestionHoursFrom? _ ht:QuestionHoursTo?
_ hs:QuestionHoursStep? QuestionSeparator
{
var question = createQuestion(id, title, type, options, placeholder, labels, required,
min, max, ml, hf, ht, hs);
return question;
}
QuestionId
= '&' id:RichText {return id}
QuestionTitle
= _ '#' title:RichText { return title }
//QuestionBody
// = content:RichText {return {type:'raw',content}}
QuestionType
= _ '~{' type: Text '}' {return type}
QuestionOptions "Options"
= options:(QuestionOption) + { return options; }
QuestionOption "Option"
= '[]' option:(RichText)
{ return option; }
QuestionPh
= _ '$' placeholder:Text {return placeholder;}
Questionlab
= _ '*' labels:Text {return labels.split(',');}
Questionreq
= _ '%'required:Text { return required }
Questionmin
= _'-min:'min:Number {return min}
Questionmax
= _ '-max:'max:Number {return max}
Questionmaxlength
= _ '-ml:'maxlength:Number {return maxlength}
QuestionHoursFrom
= _ '-hf:'hoursf:Number {return hoursf}
QuestionHoursTo
= _ '-ht:'hourst:Number {return hourst}
QuestionHoursStep
= _ '-hs:'hourstep:Number {return hourstep}
QuestionSeparator "(question separator)"
= EndOfLine EndOfLine* / EndOfLine? EndOfFile / Space*
Text "(text)"
= text:TextChar+ { return text.join(' ') }
TextChar "(text character)"
= (UnescapedChar / EscapeSequence)/ '-'
EscapeChar "(escape character)"
= '\\'
EscapeSequence "escape sequence"
= EscapeChar sequence:(
"\\"
/ "~"
/ "="
/ "#"
/ "{"
/ "}"
/ "["
/ "]"
/ "&"
/ "-"
/ "%"
/ ":"
/ "min"
/ "$")
{ return sequence; }
UnescapedChar ""
= [\u0080-\u024f] / [A-Z]i / [0-9] / ' ' / [.+><()!?:'",=/] / ('-''>') / (EndOfLine
!EndOfLine) {return ''}
ControlChar
= '=' / '~' / "#" / '{' / '}' / '$' / '*' / '[' / ']' / '-'/ '&'/ '%' / '\\'
RichText
= Text { return text().trim('') }
Number
= chars:[0-9]+ frac:NumberFraction?
{ return parseFloat(chars.join('') + frac); }
NumberFraction
= "." chars:[0-9]*
{ return "." + chars.join(''); }
_ "(whitespace)"
= (EndOfLine !EndOfLine / Space / Comment / Ignore)*
Ignore
= "[markdown]" // ignoring this for now
Comment "(comment)"
= '//' (!EndOfLine .)* ( EndOfLine / EndOfFile)
Space "(space)"
= ' ' / '\t'
EndOfLine "(end of line)"
= '\r\n' / '\n' / '\r'
EndOfFile
= !. { return "EOF"; }
Вывод следующий: