我正在为一种合成语言构建一个lexer,我在定义单行注释正则表达式时遇到了问题。
问题是注释的允许字符受到限制。只允许一些字符,它们包括:空格、数字、字母和一些符号(比如*、/、+、-)。单行注释以//开头(如C和Java),其定义(限制字符除外)与C和Java的定义相同。
首先,我尝试了以下正则表达式:
"//" ([a-zA-Z0-9] | [*] | [/] | [+] | [-] | [ \t\f])* (\r|\n|\r\n)
这很有希望捕捉到单行注释,但不幸的是,这没有捕捉到文件末尾的一行注释,因为它在末尾没有行结束符。
我试着把它改成:
"//" ([a-zA-Z0-9] | [*] | [/] | [+] | [-] | [ \t\f])* ((\r|\n|\r\n) | [^.])
希望[^.]能够抓住这样一个事实:在注释之后不允许任何字符(以某种方式模仿EOF?)但是这是行不通的,而且regex正在捕捉所有的东西,直到一个被禁止的字符,例如:// comment = 1被翻译成single line comment,=,1。
我不能使用JFlex的<<EOF>>,因为它不能是正则表达式的一部分。
对于这个问题有一个好的正则表达式解决方案吗?(假设我不能修改输入)。
谢谢!
发布于 2018-11-01 19:54:17
来自这里的jflex手册:
http://jflex.de/manual.html#Example
TraditionalComment = "/*" [^*] ~"*/" | "/*" "*"+ "/"
// Comment can be the last line of the file, without line terminator.
EndOfLineComment = "//" {InputCharacter}* {LineTerminator}?
DocumentationComment = "/**" {CommentContent} "*"+ "/"
CommentContent = ( [^*] | \*+ [^/*] )*还请注意,您可以使用%eofval来使用特定的eof值,我在上面发布的手册中也对此进行了讨论。
我知道您专门要求一个regex解决方案,但也可能有一个更好的方法通过使用您的词汇状态来简化这个问题--您可以使用符号"//“来表示注释状态的入口;一旦处于这种状态,您就可以抓取所有字母数字字符,直到到达行结束符的一行,返回一个tag.comment标记,然后转换回yyinitial状态并继续进行词法化。
例如,包括我前面讨论的所有内容:
%%
%state COMMENT
%%
%eofval{
return getToken(tag.EOF, null);
%eofval}
comment = "//"
eol = "\r\n\"
characters = [a-zA-Z0-9] | [*] | [/] | [+] | [-]
%%
<YYINITIAL> {comment}{
yybegin(COMMENT);
return getToken(tag.Comment, yytext());
}
<COMMENT> {characters}{eol}{
yybegin(YYINITIAL);
}**免责声明,这是不完整的,作为一个雷克萨斯和做在我的头顶。这将更多地演示上面讨论过的示例。
https://stackoverflow.com/questions/53033439
复制相似问题