Parsing 同时分析多行注释和字符串文字的语法
我正在尝试解析C++/Java风格的源文件,并希望将注释、字符串文本和空格作为标记进行隔离 对于空格和注释,通常建议的解决方案是(使用ANTLR语法): 但是,问题是我的源文件也由字符串文本组成,例如Parsing 同时分析多行注释和字符串文字的语法,parsing,antlr,grammar,lexer,Parsing,Antlr,Grammar,Lexer,我正在尝试解析C++/Java风格的源文件,并希望将注释、字符串文本和空格作为标记进行隔离 对于空格和注释,通常建议的解决方案是(使用ANTLR语法): 但是,问题是我的源文件也由字符串文本组成,例如 printf(" /* something looks like comment and whitespace \n"); printf(" something looks like comment and whitespace */ \n"); 内部的“东西”应该被认为是单个令牌,但
printf(" /* something looks like comment and whitespace \n");
printf(" something looks like comment and whitespace */ \n");
内部的“东西”应该被认为是单个令牌,但是我的ANTLR词条规则显然会把它们看作是MLY注释令牌:
/* something looks like comment and whitespace \n");
printf(" something looks like comment and whitespace */
但我无法创建另一个lexer规则来将令牌定义为一对内的某个东西(假设\“转义序列得到正确处理),因为这将被错误地视为字符串令牌:
/* comment...."comment that looks */ /*like a string literal"...more comment */
简而言之,2对/**/和“”将相互干扰,因为每对都可以包含另一对的开头作为其有效内容。那么我们应该如何定义一个lexer语法来处理这两种情况呢
JavaMan写道:
我正在尝试解析C++/Java风格的源文件,并希望将注释、字符串文字和空白分隔为标记
您不应该也匹配字符文本吗?考虑:
charc='”;
不应将双引号视为字符串文字的开头
JavaMan写道:
简而言之,2对/**/和“”将相互干扰
错误,不是。如果一个/*
首先被“看到”,它将一直消耗到第一个*/
。对于以下输入:
/*注释…“看起来像字符串文字的注释”…更多注释*/
这意味着双引号也会被使用。字符串文字也是如此:当首先看到双引号时,/*
和/或*/
将被使用,直到遇到下一个(未转义)“
还是我误解了
请注意,您可以在*
或+
之前从语法中删除选项{greedy=false;}:
,这些选项默认为取消冻结
这里有一个方法:
语法T;
作语法分析
:(t=。
{
如果($t.type!=其他){
System.out.printf(“\%-10s>\%s<
空间><
空间><
字符串>“foo\t/*bar*/baz”<
空间>
<
空间><
空间><
空间><
字符>“”<
空间><
SL_COMMENT>//COMMENT/*此处<
空间>
<
ML_COMMENT>/*多个“无字符串”
线*/<
基本上,您的问题是:在字符串文本中,注释(/*和//)必须忽略,反之亦然。在我看来,这只能通过顺序读取来解决。在逐个字符地遍历源文件时,您可以将其作为状态机处理,其中包含状态文本、BlockComment、LineComment和StringLiteral
这是一个很难用正则表达式甚至语法来解决的问题
请注意,任何C/C++/C#/Java lexer都需要处理完全相同的问题。我很确定它采用了类似于状态机的解决方案。因此,如果可以的话,我的建议是,以这种方式定制您的lexer。谢谢,您是对的。我对lexer规则工作方式的误解。顺便说一句,SL|U注释中的~('\r'.\n')*等同于(~('\r'|'\n'))*?@JavaMan,是的,
~('\r'|'\n')*
与(~('\r'|'\n'))*
是另一个lexer规则必须的吗?如果一个字符不能与任何lexer规则匹配,会发生什么情况?@JavaMan,lexer会发出“sees”的警告任何lexer规则都不匹配的字符。因此,是的,其他
规则必须在其中。“这是一个很难用正则表达式甚至语法解决的问题。”,不,不是。它可以很容易地翻译成几个正则表达式:看我的答案。你答案的高度复杂性使我提供了这个答案作为替代。你的答案可能是这个特殊情况下的解决方案,但不值得羡慕。我不同意我的答案是复杂的:一个只有基本知识的人当然,ANTLR可以理解。此外,你所说的是不正确的:OP问题的解决方案是一对正则表达式(语法是正则的!)。即使在这种情况下,它也是正确的。但是你的解决方案很直接。尽管如此,我发现它是可以解释的。同意不同意。
/* comment...."comment that looks */ /*like a string literal"...more comment */