如果在antlr4 lexer中有一个ONELINE_STRING片段规则标识一行上的一个简单引号字符串,那么如何在lexer中创建一个更通用的字符串规则,该规则将相邻的ONELINE_STRING连接起来(即,只要它们都在不同的行上开始,仅用空格和/或注释分隔)?
即,
"foo" "bar"
将被解析为两个字符串标记,“foo”后跟“bar”
同时:
"foo"
"bar"
示例1:
"desc" "this sample will parse as two strings.
Sample3(注意,'output'是该语言中的关键字):
output "this is a very long line that I've explicitly made so that it does not "
"easily fit on just one line, so it gets split up into separate ones for "
"ease of reading, but the parser should see it all as one long string. "
"This example will parse as if the output command had been followed by "
"only a single string, even though it is composed of multiple string "
"fragments, all of which should be invisible to the parser.%n";
这两个示例都应该被解析器接受为有效。前者是声明的例子,而后者是语言中命令语句的例子。
但是,我一直在想,可以使用ONELINE_STRING作为lexer规则,并使用一个通用的'string'解析器规则来检测相邻的ONELINE_STRINGS,在字符串之间使用谓词来检测下一个ONELINE_STRING标记是否开始于与前一个不同的行,如果是,它应该不可见地将它们连接起来,这样它的文本就无法与在一行上指定的字符串区分开来。然而,我不确定这将如何实施。
好吧,我拿到了。
正如你们中的一些人所建议的那样,我需要在解析器中有字符串识别器。诀窍是在lexer中使用lexer模式。
BEGIN_STRING : '"' -> pushMode(StringMode);
mode StringMode;
END_STRING: '"'-> popMode;
STRING_LITERAL_TEXT : ~[\r\n%"];
STRING_LITERAL_ESCAPE_QUOTE : '%"' { setText("\""); };
STRING_LITERAL_ESCAPE_PERCENT: '%%' { setText("%"); };
STRING_LITERAL_ESCAPE_NEWLINE : '%n'{ setText("\n"); };
UNTERMINATED_STRING: { _input.LA(1) == '\n' || _input.LA(1) == '\r' || _input.LA(1) == EOF}? -> popMode;
string returns [String text] locals [int line] : a=stringLiteral { $line = $a.line; $text=$a.text;}
({_input.LT(1)!=null && _input.LT(1).getLine()>$line}?
a=stringLiteral { $line = $a.line; $text+=$a.text; })*
;
stringLiteral returns [int line, String text]: BEGIN_STRING {$text = "";}
(a=(STRING_LITERAL_TEXT
| STRING_LITERAL_ESCAPE_NEWLINE
| STRING_LITERAL_ESCAPE_QUOTE
| STRING_LITERAL_ESCAPE_PERCENT
) {$text+=$a.text;} )*
stringEnd { $line = $BEGIN_STRING.line; }
;
stringEnd: END_STRING #string_finish
| UNTERMINATED_STRING #string_hang
;
因此,只要相邻的字符串字元位于不同的行上,字符串规则就会将它们串联起来。stringEnd规则需要一个事件处理程序,用于当字符串文本没有正确终止时,这样解析器就可以报告语法错误,但在其他情况下,字符串将被视为正确关闭。
编辑:对不起,没有完全阅读您的要求。下面的方法将匹配两个示例,而不仅仅是所需的示例。得好好想想...
最简单的方法是在解析器中执行此操作。我认为没有必要要求在lexer中这样做。
multiString : singleString +;
singleString : ONELINE_STRING;
ONELINE_STRING: ...; // no fragment!
WS : ... -> skip;
Comment : ... -> skip;
在我的作业中,我对字符串Lexer有以下描述: “字符串文字由零个或多个用双引号(”“)括起的字符组成。使用转义序列(如下所列)表示字符串中的特殊字符。在字符串文本中出现新行或EOF字符是编译时错误。 所有支持的转义序列如下: \b退格 \f formfeed \r回车 \n换行符 \t水平选项卡 \“双引号 \反斜杠 以下是字符串文字的有效示例: "这是一个包含制表符\t的字符串" "他问我:\
我有一种使用模式进行字符串插值的语法:大致如下: 现在这工作和标记一切主要是我想要的,但它确实有2个缺陷。 如果RBRACES的数量过多,它会弹出第一个默认模式,这会使IDE出现故障,而不仅仅是显示错误。 关闭块和关闭插值的标记是相同的,因此我无法根据需要突出显示它们。(这是主要的) 我的IDE仅基于令牌突出显示,所以这是一个问题,我希望能够以不同的方式突出显示它们。所以基本上我想要一个解决方案,
null null 以下是我的(不完整和不成功的)尝试: 如果不能在lexer中解决这个问题,我可以使用标记、、、、、和自行编写解析器规则。
本文向大家介绍groovy 多行字符串,包括了groovy 多行字符串的使用技巧和注意事项,需要的朋友参考一下 示例
控制字符序列以'\为前缀,以\\结尾。在控制序列中有两个数字,它们指定控制字符。 在上面的示例中,结果字符串为 ESC代表不可打印的ASCII转义字符。 输入'a string'\ctrl\''会产生错误 你知道吗?顺便说一句:我们使用的是antlr V4.5。
本文向大家介绍groovy 多行字符串(多余的换行符),包括了groovy 多行字符串(多余的换行符)的使用技巧和注意事项,需要的朋友参考一下 示例