我正在努力编写一条能够捕捉各种评论甚至“未发表评论”错误的规则。
这是基于Pascal的语言。评论可以是以下形式:
(* ...with any characters within... *)
(*
* separated onto multiple lines
*)
(* they can contain "any" symbol, so -, +, :, ; , etc. should be ignored *)
但我需要发现任何评论错误,例如:
(* this comment has no closing r-parenthesis *
或(* this comment is missing an asterisk )
到目前为止,我有这个:
{%
int yylval;
vector<string> string_table;
int string_table_index = 0;
int yyline = 1, yycolumn = 1;
%}
delim [ \t\n]
ws {delim}+
letter [a-zA-Z]
digit [0-9]
id {letter}({letter}|{digit})*
number {digit}+
float {digit}+(\.{digit}+)?(E[+\-]?{digit}+)?
%%
{ws} {yycolumn += yyleng;}
"(*" {
int c;
yycolumn += yyleng;
while ((c = yyinput()) != '*' && c != EOF) {
c = yyinput(); /* read additional text */
if (c == '*') {
while ((c = yyinput()) == '*') {
c = yyinput();
if (c == ')') {
break; /* found the end */
} else if (c == EOF) {
cout << "EOF in comment\n";
break;
} else {
cout << "unended comment, line = "
<< yyline << ", column = "
<< yycolumn-yyleng << "\n";
}
}
}
}
}
RPARENtoken
!),MINUStoken
)我不确定它是否正确捕捉未发表的评论错误。
我想我很亲密......谁能看到我哪里出错?
答案 0 :(得分:4)
考虑使用start conditions以避免必须以(*
模式编写所有额外代码。我在下面写了一个简短的例子。
%x COMMENT
%%
"(*" { BEGIN(COMMENT); }
<COMMENT>{
"*)" { BEGIN(INITIAL); }
<<EOF>> { printf("EOF in comment\n"); }
. {}
}
基本上,当词法分析器找到注释的开头时,它会进入COMMENT
状态,并且只会检查<COMMENT>
块内的规则。当找到*)
时,它将返回初始状态。请注意,如果您计划使用多个州,则最好使用yy_push_state(COMMENT)
和yy_pop_state(COMMENT)
代替BEGIN(STATENAME)
。
我不完全确定您的评论错误标准是什么(例如,它与评论中遇到EOF的方式有何不同),但这可能会扩展到处理这些情况。