首页 > 解决方案 > 使用嵌入的多行控制字符序列解析字符串

问题描述

我正在为实时编程语言 PEARL 编写编译器。PEARL 支持带有嵌入式控制字符序列的字符串,例如

'some text'\1B 1B 1B\'some more text'.

控制字符序列以 '\ 为前缀,以 \' 结束。控制序列内部是两位数字,用于指定控制字符。

在上面的示例中,生成的字符串将是

'some textESCESCESCsome more text'

ESC 代表不可打印的 ASCII 转义字符。

此外,在控制字符序列内允许换行符构建多行字符串,例如

'some text'\1B 
1B 
1B\'some more text'.

这导致与上面相同的字符串。

grammar stringliteral;

tokens {
    CHAR,CHARS,CTRLCHARS,ESC,WHITESPACE,NEWLINE
}

stringLiteral:  '\'' CHARS? '\'' ;

fragment
CHARS: CHAR+ ;

fragment
CHAR: CTRLCHARS | ~['\n\r] ;

fragment
ESC: '\'\\' ;

fragment
CTRLCHARS: ESC ~['] ESC;

WHITESPACE: (' ' | '\t')+ -> channel(HIDDEN);

NEWLINE: ( '\r' '\n'? | '\n' ) -> channel(HIDDEN);

上面的词法分析器/解析器的行为非常奇怪,因为它只接受“x”形式的字符串,并忽略多个字符和控制字符序列。

可能我正在监督一些明显的事情。欢迎任何提示或想法如何解决这个问题!

我现在根据 Mike 的提示更正了语法:

grammar stringliteral;

tokens {
     STRING
}

stringLiteral: STRING;
STRING: '\'' ( '\'' '\\' | '\\' '\'' | . )*? '\'';

对控制字符序列结束的识别仍然存在问题:

输入 'A STRING'\CTRL\'' 产生错误

Line 1:10 token recognition error at: '\'
line 1:11 token recognition error at: 'C'
line 1:12 token recognition error at: 'T'
line 1:13 token recognition error at: 'R'
line 1:14 token recognition error at: 'L'
line 1:15 token recognition error at: '\'

任何想法?顺便说一句:我们使用的是 antlr v 4.5。

标签: antlrantlr4

解决方案


我通过调整最新的 java 语法示例中的适当规则解决了这个语法片段的问题:

StringLiteral
    :   '\'' StringCharacters? '\''
    ;

fragment
StringCharacters
    :   StringCharacter+
    ;

fragment
StringCharacter
    :   ~['\\\r\n]
    |   EscapeSequence
    ;

fragment
EscapeSequence
    : '\'\\' (HexEscape| ' ' | [\r\n])* '\\\''
    ;

fragment
HexEscape
    :  B4Digit B4Digit
    ;

fragment
B4Digit
    : '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | 'A' | 'B' |     'C' | 'D' | 'E' | 'F'
    ;

推荐阅读