Разбор файла локализуемых строк iOS / macOS с помощью antlr4 - PullRequest
0 голосов
/ 25 сентября 2018

Я пытаюсь проанализировать локализованные «строковые» файлы macOS / iOS.

Формат этого файла основан на парах ключ / значение с необязательными комментариями.Вот пример:

/* This is a comment */
// This is also a comment

"key1" = "value1";

"key2" = "value2";

и так далее. ПРИМЕЧАНИЕ внутри "" может быть абсолютно любой вид текста.

РЕДАКТИРОВАТЬ Исходная грамматика errorneus удалена

Я пыталсянаписать эту простую грамматику, но, к сожалению, она не работает.

Поскольку содержимое внутри кавычек может быть довольно сложным, не говоря уже о комментариях, я чувствую, что обычное регулярное выражение не имеет реальной силы там.

РЕДАКТИРОВАТЬ на основе комментариев @GRosenberg Я создал новую грамматику.Теперь у меня проблема в том, что я не могу включить «Символы» в качестве 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
        )
    ;

1 Ответ

0 голосов
/ 25 сентября 2018

Хранилище грамматики 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] ;
...