antlr - 使用嵌入的多行控制字符序列解析字符串
问题描述
我正在为实时编程语言 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。
解决方案
我通过调整最新的 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'
;
推荐阅读
- c++ - 通过加法溢出变量
- android - Kotlin - 通过片段传递参数
- java - 如何创建 .JAR 来执行特定任务,然后在另一个项目中使用这个 JAR?
- python - 计算 Spark 中两列之间的余弦距离
- javascript - Bot framework v4 Node.js:如何根据外部触发器进入下一个瀑布步骤(发布请求)
- c# - 无法解析来自 Asp.Net WebApi(TFS 类)的依赖项
- php - 无法与主机 smtp.gmail.com 建立连接:stream_socket_client():无法连接到 ssl://smtp.gmail.com:465
- python - 如何更正确地近似点
- laravel - 电子邮件未在注册控制器中发送
- javascript - 未找到 Vue 原生模块:无法解析 '../../App'