处理以ANTLR4中的转义引号结尾的字符串文字

时间:2014-07-03 15:36:31

标签: antlr4

如何编写词法分析器规则以匹配不以转义引用结尾的字符串文字?

这是我的语法:

lexer grammar StringLexer;

// from The Definitive ANTLR 4 Reference
STRING: '"' (ESC|.)*? '"';
fragment ESC : '\\"' | '\\\\' ;

这是我的java块:

String s = "\"\\\""; // looks like "\"
StringLexer lexer = new StringLexer(new ANTLRInputStream(s)); 

Token t = lexer.nextToken();

if (t.getType() == StringLexer.STRING) {
    System.out.println("Saw a String");
}
else {
    System.out.println("Nope");
}

这会输出Saw a String"\"是否真的与STRING匹配?

编辑: 280Z28和Bart的解决方案都是很好的解决方案,不幸的是我只能接受一个。

2 个答案:

答案 0 :(得分:9)

对于正确形成的输入,词法分析器将匹配您期望的文本。但是,使用非贪婪的运算符不会阻止它与以下形式匹配:

'"' .*? '"'

确保字符串是最符合标准的标记"#34;方式可行,我建议使用以下规则。

StringLiteral
  : UnterminatedStringLiteral '"'
  ;

UnterminatedStringLiteral
  : '"' (~["\\\r\n] | '\\' (. | EOF))*
  ;

如果您的语言允许字符串文字跨越多行,您可能需要修改UnterminatedStringLiteral以允许匹配行尾字符。

如果您不包含UnterminatedStringLiteral规则,词法分析器将通过简单地忽略字符串的开始"字符并继续标记字符串的内容来处理未终止的字符串。

答案 1 :(得分:4)

是的,"\"STRING规则匹配:

            STRING: '"' (ESC|.)*? '"';
                     ^       ^     ^
                     |       |     |
// matches:          "       \     "

如果您不希望.与反斜杠(和引号)匹配,请执行以下操作:

STRING: '"' ( ESC | ~[\\"] )* '"';

如果您的字符串无法分布在多行上,请执行以下操作:

STRING: '"' ( ESC | ~[\\"\r\n] )* '"';