我正在使用ANTLR4并在编写语法的过程中处理单引号和双引号字符串。我正在尝试使用Lexer模式来调整字符串的范围,但这对我来说不起作用,我的语法如下所示。这是正确的方法,或者我如何正确地将这些解析为令牌而不是带有上下文的解析器规则。有什么见解吗?
一个例子:
'single quote that contain "a double quote 'that has another single quote'"'
Lexer Grammar
lexer grammar StringLexer;
fragment SQUOTE: '\'';
fragment QUOTE: '"';
SQSTR_START: SQUOTE -> pushMode(SQSTR_MODE);
DQSTR_START: QUOTE -> pushMode(DQSTR_MODE);
CONTENTS: ~["\']+;
mode SQSTR_MODE;
SQSTR_END: (CONTENTS | DQSTR_START)+ SQUOTE -> popMode;
mode DQSTR_MODE;
DQSTR_END:(CONTENTS | SQSTR_START)+ QUOTE -> popMode;
分析器
parser grammar StringParser;
options { tokenVocab=StringLexer; }
start:
dqstr | sqstr
;
dqstr:
DQSTR_START DQSTR_END
;
sqstr:
SQSTR_START SQSTR_END
;
附录 谢谢@Lucas Trzesniewski的回答。
这是语法的一部分我正在编写解析类似shell的语言,我可以有多行脚本,他们会有SQSTR
和DQSTR
。通过答案中提供的词法分析器规则,它可以将多行脚本放在一起。
快乐案例(使用答案正确解析):
cmd 'single quote string'
cmd2 "double quote"
cmd3 'another single quote'
这被认为是三个命令和三个字符串(单个和双重)
Unparsed示例:另一方面 - 请注意单引号字符串中的引号:
cmd 'single "quote string'
cmd2 "double quote"
cmd3 'another "single quote'
在这种情况下,它会错误地将所有这些检测为SQSTR类型的单个字符串标记。
有任何想法如何解决这个问题?
答案 0 :(得分:2)
如果要将示例字符串解析为单个标记,则不必使用词法分析器模式,您可以使用相互递归的词法分析器规则:
SQSTR : '\'' (~['"] | DQSTR)* '\'';
DQSTR : '"' (~['"] | SQSTR)* '"';
然后,在解析器中使用类似的东西:
str : SQSTR | DQSTR;
答案 1 :(得分:0)
方式太复杂了,你有什么想法。你以前在哪里看过这样的解决方案? (几乎)github上语法存储库中所有具有此类规则的语法都使用简单且工作良好的方法,其中您有一个导入器,内容和终结符,所有这些都在一个规则中,例如:
SQSTRING: '\'' .*? '\'';
DQSTRING: '"' .*? '"';
类似地,对于具有这种结构的所有其他元素(单引号字符串,反引号引用字符串,多行注释等)。