Недавно я начал использовать ANTLR для создания простого синтаксического анализа для интерполированных строк. Некоторые примеры входной строки следуют (по одному в каждой строке):Как сделать правило ANTLR «жадным»?
Hello {User.Name}!
Welcome on Planet {GetPlanetName(" A stupid string param :-} ")}
Plain String without an interpolated expression
String with escaped {{ brackets }}
грамматику, чтобы решить, следует ли что-то строка (plainString) или выражение (expressionString) выглядит следующим образом :
grammar T;
patternString: (plainString | expressionString)+
;
plainString: (CBO_ESCAPESEQUENCE | CBC_ESCAPESEQUENCE | PLAINSTRINGLITERAL)+
;
expressionString: CBO expression CBC | CURLYBRACKETS_EMPTY
;
expression: expressionSegment+
;
expressionSegment: ~('"' | '\'' | '{' | '(' | '[' | '}' | ')' | ']' | CBO_ESCAPESEQUENCE | CBC_ESCAPESEQUENCE)+
| '(' expressionSegment+ ')' | '(' WS ')' | '()'
| '[' expressionSegment+ ']' | '[' WS ']' | '[]'
| '{' expressionSegment+ '}' | CURLYBRACKETS_EMPTY
| stringLiteral
| charLiteral
;
stringLiteral: '"' (~('"') | '\\"')+ '"'
| '""'
;
charLiteral: '\'' (~('\'') | '\\\'')+ '\''
;
fragment WS: (' ' | '\r' | '\n' | '\t')+;
PLAINSTRINGLITERAL: ~('{' | '}');
CURLYBRACKETS_EMPTY: (CBO WS CBC | CBO CBC);
CBO: '{';
CBC: '}';
fragment CBO_ESCAPESEQUENCE: '{{';
fragment CBC_ESCAPESEQUENCE: '}}';
Это работает очень хорошо для некоторых строк, как за исключением следующего:
{{{новый [] {1, 2, 3, 4}}}}
Который дает мне следующее AST
PatternString => '{{{new[]{1, 2, 3, 4}}}}'
ExpressionString => '{{{new[]{1, 2, 3, 4}}}}'
Expression => '{{new[]{1, 2, 3, 4}}}'
ExpressionSegment => '{{new[]{1, 2, 3, 4}}}'
ExpressionSegment => '{new[]{1, 2, 3, 4}}'
ExpressionSegment => 'new[]'
ExpressionSegment => '{1, 2, 3, 4}'
ExpressionSegment => '1, 2, 3, 4'
в то время как я хотел бы ожидать (и хотят) следующий AST:
PatternString => '{{{new[]{1, 2, 3, 4}}}}'
PlainString => '{{'
ExpressionString => '{new[]{1, 2, 3, 4}}'
Expression => 'new[]{1, 2, 3, 4}'
ExpressionSegment => 'new[]'
ExpressionSegment => '{1, 2, 3, 4}'
ExpressionSegment => '1, 2, 3, 4'
PlainString => '}}'
Значение, plainString
должны быть более жадным и взять столько побег d скобки. Как я могу исправить это в вышеупомянутой грамматике?
После быстрой проверки его кажется, работает отлично! Завтра мои юниты проведут тесты и дадут вам знать результаты! – Markus
Прекрасно работает! Большое спасибо! – Markus