Я пытаюсь разобрать локализованные «строковые» файлы macOS / iOS.
Формат этого файла основан на парах ключ / значение с дополнительными комментариями. Пример ниже:
/* This is a comment */
// This is also a comment
"key1" = "value1";
"key2" = "value2";
и так далее. ПРИМЕЧАНИЕ внутри "" может быть текстом типа абсолютно любой.
РЕДАКТИРОВАТЬ Исходная грамматика errorneus удалена
Я пытался написать эту простую грамматику, но, к сожалению, это не сработало.
Поскольку содержимое внутри кавычек может быть довольно сложным, не говоря уже о комментариях, я считаю, что обычное регулярное выражение здесь не имеет реальной силы.
РЕДАКТИРОВАТЬ на основе комментариев @GRosenberg Я создал новую грамматику. Теперь у меня проблема, что я не могу включить «Symbols» как Char, иначе синтаксический анализ сломается.
grammar LProj;
Esc : '\\';
Spaces : [ \t\r\n\f]+;
BlockComment : '/*' .*? ('*/' | EOF) ;
LineComment : '//' ~[\r\n]* ( '\r'? '\n' [ \t]* '//' ~[\r\n]* )* ;
MLN_COMMENT: BlockComment -> channel(HIDDEN) ;
SLN_COMMENT: LineComment -> channel(HIDDEN) ;
doc : expression*;
expression
: BlockComment
| LineComment
| Spaces
| entry
;
entry : '"' key=VALUE '"' Spaces? '=' Spaces? '"' value=VALUE '"' Spaces? ';' ;
VALUE : ( EscSeq | Val )+ ;
fragment Val : Char ( EscSeq | Char )* ;
fragment Symbol
: '*'
| '/'
| ';'
| '='
;
fragment Char
: Spaces
| '!' // skip "
| '#'..')' // skip *
| '+'..'.' // skip /
| '0'..':' // skip ;
| '<' // skip =
| '>'..'[' // skip \
| ']'..'~'
| '\u00B7'..'\ufffd'
; // ignores | ['\u10000-'\uEFFFF] ;
fragment UnicodeEsc
: 'u' (Hex (Hex (Hex Hex?)?)?)?
;
fragment Hex : [0-9a-fA-F] ;
fragment EscSeq
: Esc
( [btnfr"\\] // standard escaped character set
| UnicodeEsc // standard Unicode escape sequence
| . // Invalid escape character
| EOF // Incomplete at EOF
)
;
Репозиторий грамматики Antlr предоставляет хорошие примеры того, как достичь заявленной цели. Просто определите терминал ID
, чтобы включить escape-последовательности.
Таким образом (с опущенными очевидными деталями),
id : QUOTE key=ID EQ val=ID QUOTE ;
DOC_COMMENT: DocComment -> channel(HIDDEN) ;
MLN_COMMENT: BlockComment -> channel(HIDDEN) ;
SLN_COMMENT: LineComment -> channel(HIDDEN) ;
NAME : NameStartChar NameChar* ;
VALUE : ( EsqSeq | Val )+ ;
fragment Val : NameStartChar ( EsqSeq | NameChar )* ;
fragment Hws : [ \t] ;
fragment Vws : [\r\n\f] ;
fragment DocComment : '/**' .*? ('*/' | EOF) ;
fragment BlockComment : '/*' .*? ('*/' | EOF) ;
fragment LineComment : '//' ~[\r\n]* ( '\r'? '\n' Hws* '//' ~[\r\n]* )* ;
// escaped short-cut character or Unicode literal
fragment EscSeq
: Esc
( [btnfr"\\] // standard escaped character set
| UnicodeEsc // standard Unicode escape sequence
| . // Invalid escape character
| EOF // Incomplete at EOF
)
;
fragment Esc : '\\' ;
fragment UnicodeEsc
: 'u' (Hex (Hex (Hex Hex?)?)?)?
;
// A valid hex digit
fragment Hex : [0-9a-fA-F] ;
fragment NameChar
: NameStartChar
| '0'..'9'
| '_'
| '\u00B7'
| '\u0300'..'\u036F'
| '\u203F'..'\u2040'
;
fragment NameStartChar
: 'A'..'Z'
| 'a'..'z'
| '\u00C0'..'\u00D6'
| '\u00D8'..'\u00F6'
| '\u00F8'..'\u02FF'
| '\u0370'..'\u037D'
| '\u037F'..'\u1FFF'
| '\u200C'..'\u200D'
| '\u2070'..'\u218F'
| '\u2C00'..'\u2FEF'
| '\u3001'..'\uD7FF'
| '\uF900'..'\uFDCF'
| '\uFDF0'..'\uFFFD'
; // ignores | ['\u10000-'\uEFFFF] ;
Кое-где взяты из грамматик, хотя в основном из грамматик Antlr и Java.
См. Правки. Лучше всего просто скрыть комментарии от лексера для последующего доступа при просмотре дерева синтаксического анализа.
Я добавил channel(HIDDEN)
, как предлагалось, но все равно не повезло. Я обновил свой вопрос, чтобы отразить это изменение.
Symbol
- это фрагмент, который никогда не использовался. Совершенно непонятно, почему включение символов в определение Char
может что-либо сломать, учитывая определение проблемы, по крайней мере, в том виде, в каком оно было опубликовано. BlockComment
и LineComment
должны быть фрагментами. Если это фрагменты, они не могут быть сопоставлены в правиле синтаксического анализатора.
Откуда вы взяли этот пример? Комментарии (например, DocComment), похоже, не упоминаются, и у меня есть проблемы с их правильной интеграцией.