Я думаю, что у меня может быть еще одна проблема, но я не совсем уверен. Язык, на котором я пишу, должен поддерживать многострочные операторы if, а также однострочные, т.е.
if(conditions){
print "multi";
print "line";
}
и
if(conditions)
print "single line"
Что на моем языке соответствует
if conditions then begin
end
и
if conditions then
Мне также нужно добавить поддержку else-if и else, используя тот же синтаксис, что и выше, для начала и конца. Я потратил некоторое время, пытаясь заставить это работать, и я приблизился, но с грамматикой, которую я использую сейчас, я получаю ошибку «у этого ввода более одной действительной интерпретации ...». Вот код MGrammar, который я использую:
syntax sIf = tIf conditions:Common.List(sBooleanExpression) tThen sBegin statements:sStatements2 (tEnd | tEnd2) next:Common.List(sElseIf)?
=> If{Conditions{conditions}, Body{statements}, Next{next}}
| tIf conditions:Common.List(sBooleanExpression) tThen statement:sSingleStatement next:Common.List(sElseIf)?
=> SingleIf{Conditions{conditions}, Body{statement}, Next{next}}
;
syntax sElseIf = tElseIf conditions:Common.List(sBooleanExpression) tThen sBegin statements:sStatements2 (tEnd | tEnd2) next:Common.List(sElseIf)?
=> ElseIf{Conditions{conditions}, Body{statements}, Next{next}}
| tElseIf conditions:Common.List(sBooleanExpression) tThen statement:sSingleStatement next:Common.List(sElseIf)?
=> ElseIf{Conditions{conditions}, Body{statement}, Next{next}}
| e:sElse => e;
syntax sElse = tElse tThen sBegin es:sStatements2 (tEnd | tEnd2) => Else{Body{es}}
| tElse statement:sSingleStatement => Else{Body{statement}}
;
Это, вероятно, десятая версия, поскольку я пробовал разные вещи, чтобы заставить работать структуру if / else if / else.
По сути, мой главный получает список утверждений, если он один из них. sIf пытается найти многострочный или однострочный оператор if, за которым следует sElseIf, который является необязательным (вам не нужно использовать else).
Я думаю, что проблема в том, что компилятор регулярного выражения может видеть else в качестве sElse, за которым следует оператор sIf вместо оператора sElseIf. В режиме предварительного просмотра оно на самом деле рисует дерево именно так, как я хочу, поэтому, если есть способ игнорировать это сообщение, когда я анализирую его в моем приложении на C #, тогда это тоже будет работать.