Анализ файла локализуемых строк iOS / macOS с помощью antlr4

Я пытаюсь разобрать локализованные «строковые» файлы 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
        )
    ;
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
127
1

Ответы 1

Репозиторий грамматики 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] ;

Откуда вы взяли этот пример? Комментарии (например, DocComment), похоже, не упоминаются, и у меня есть проблемы с их правильной интеграцией.

Panayotis 25.09.2018 09:39

Кое-где взяты из грамматик, хотя в основном из грамматик Antlr и Java.

GRosenberg 25.09.2018 21:32

См. Правки. Лучше всего просто скрыть комментарии от лексера для последующего доступа при просмотре дерева синтаксического анализа.

GRosenberg 25.09.2018 21:40

Я добавил channel(HIDDEN), как предлагалось, но все равно не повезло. Я обновил свой вопрос, чтобы отразить это изменение.

Panayotis 27.09.2018 12:06
Symbol - это фрагмент, который никогда не использовался. Совершенно непонятно, почему включение символов в определение Char может что-либо сломать, учитывая определение проблемы, по крайней мере, в том виде, в каком оно было опубликовано. BlockComment и LineComment должны быть фрагментами. Если это фрагменты, они не могут быть сопоставлены в правиле синтаксического анализатора.
GRosenberg 27.09.2018 22:02

Другие вопросы по теме