Intellij idea JFlex:在匹配过程中如何让文本继续

Intellij idea JFlex:在匹配过程中如何让文本继续,intellij-idea,jflex,Intellij Idea,Jflex,我正在尝试为IntelliJ语言插件编写一个lexer。在JFLex中,有一个示例可以使用lex字符串文本。然而,在本例中,他们使用StringBuffer来插入词法字符的每一部分,并持续构建单个字符串。这个方法的问题是,它会创建一个正在读取的字符的副本,我不知道如何将该示例与IntelliJ集成。在IntelliJ中,始终返回IElementType,然后使用函数getTokenStart和getTokenEnd从yytext中获取相关文本,这样整个令牌的开始和结束直接映射到输入字符串 因此,

我正在尝试为IntelliJ语言插件编写一个lexer。在JFLex中,有一个示例可以使用lex字符串文本。然而,在本例中,他们使用StringBuffer来插入词法字符的每一部分,并持续构建单个字符串。这个方法的问题是,它会创建一个正在读取的字符的副本,我不知道如何将该示例与IntelliJ集成。在IntelliJ中,始终返回IElementType,然后使用函数getTokenStart和getTokenEnd从yytext中获取相关文本,这样整个令牌的开始和结束直接映射到输入字符串

因此,我希望能够返回一个令牌,并且自上次返回另一个令牌以来,关联的文本应该跨越整个文本。例如,在string-literal示例中,我将读取\以标记文本开始,然后我将更改为state-string,当我再次读取\时,我将更改回另一个状态并返回string-literal标记。此时,我希望yytext包含整个字符串文本


JFlex是否可以实现这一点?如果没有,那么在匹配了跨越多个操作的令牌之后,建议将内容从StringBuffer传递到IntelliJ API的原因是什么。

您可以编写一个与整个字符串文本匹配的正则表达式,以便在一次文本调用中获得它,但此匹配将包含未处理的转义序列

从JFlex java示例中:

<STRING> {
  \"                             { yybegin(YYINITIAL); return symbol(STRING_LITERAL, string.toString()); }

  {StringCharacter}+             { string.append( yytext() ); }

  /* escape sequences */
  "\\b"                          { string.append( '\b' ); }
  "\\t"                          { string.append( '\t' ); }
  "\\n"                          { string.append( '\n' ); }
  "\\f"                          { string.append( '\f' ); }
  "\\r"                          { string.append( '\r' ); }
  "\\\""                         { string.append( '\"' ); }
  "\\'"                          { string.append( '\'' ); }
  "\\\\"                         { string.append( '\\' ); }
  \\[0-3]?{OctDigit}?{OctDigit}  { char val = (char) Integer.parseInt(yytext().substring(1),8);
                                           string.append( val ); }

  /* error cases */
  \\.                            { throw new RuntimeException("Illegal escape sequence \""+yytext()+"\""); }
  {LineTerminator}               { throw new RuntimeException("Unterminated string at end of line"); }
}
但是yytext将包含未处理的序列\\t,而不是字符'\t'

如果这是可以接受的,那么这就是简单的解决方案。如果令牌应该是输入的实际子字符串,那么听起来这就是您想要的

如果不是,您将需要更复杂的东西,例如一个中间接口函数,它不是yytext,但在最后一个匹配是字符串匹配时返回StringBuffer内容,可以在字符串操作中设置一个标志,否则返回yytext

\" ({StringCharacter} | \\[0-3]?{OctDigit}?{OctDigit} | "\\b" | "\\t" | .. | "\\\\") * \"