我试图在下面的代码中找出哪里出了问题。
弹性输入:
%{
#include "jq.tab.h"
void yyerror(char *);
%}
method add|map|.. and other methods go here
%%
"/*" { return CS; }
"*/" { return CE; }
"jQuery" {
printf("%s is yytext\n", yytext);
return *yytext;
}
"args" { return ARGUMENT; }
{method} { return METHOD; }
[().\n] { return *yytext; }
[ \t]+ { return WS; }
. { return IGNORE; }
%%
int yywrap(void) {
return 1;
}
野牛输入:
%{
#include <stdio.h>
int yylex(void);
void yyerror(char *);
%}
%token ARGUMENT METHOD IGNORE WS CS CE
%error-verbose
%%
stmts:
stmt '\n' { printf("A single stmt\n"); }
| stmt '\n' stmts { printf("Multi stmts\n"); }
;
stmt:
jQuerycall { printf("A complete call ends here\n"); }
| ignorechars { printf("Ignoring\n"); }
| ignorechars WS jQuerycall { printf("ignore+js\n"); }
| jQuerycall WS ignorechars { printf("js+ignore\n"); }
| optionalws stmt optionalws
| CS stmt CE { printf("comment\n"); }
;
jQuerycall:
'jQuery' '(' ARGUMENT ')' '.' methodchain { printf("args n methodchain\n"); }
| 'jQuery' '(' ')' '.' methodchain { printf("methodchain\n"); }
| 'jQuery' '(' ARGUMENT ')' { printf("args\n"); }
| 'jQuery' '(' ')' { printf("empty call\n"); }
;
methodchain:
methodchain '.' methodcall
| methodcall
;
methodcall:
METHOD '(' ')'
;
ignorechars:
IGNORE
| IGNORE optionalws ignorechars
;
optionalws:
| WS
;
%%
void yyerror(char *s) {
fprintf(stderr, "%s\n", s);
}
int main(void) {
yyparse();
return 0;
}
我的目标是识别所有具有其所有元素的jQuery调用,并忽略任何其他语句/字符串。也忽略评论。现在,此代码有许多假设-像“ args”是jQuery()中唯一的选择器元素。
我正在使用以下输入输出情况。我正在尝试找出类似10和12的情况:
> 1.input: statement\n output: Ignoring
>
> 2.input: statement statement\n output: Ignoring
>
> 3.input: statement statement statement\n output: Ignoring
>
> 4.input: jQuery()\n output: jQuery is yytext empty call A complete call ends here
>
> 5.input: jQuery(args)\n output: jQuery is yytext args A complete call ends here
>
> 6.input: jQuery().add()\n output: jQuery is yytext methodchain A complete call ends here
>
> 7.input: jQuery(args).add().map()\n output: jQuery is yytext args n methodchain A complete call ends here
>
> 8.input: /*comment*/\n output: Ignoring comment
>
> 9.input: /*jQuery()*/\n output: jQuery is yytext empty call A complete call ends here comment
>
> 10.input: /* comment */\n output: syntax error, unexpected CE, expecting IGNORE
>
> 11.input: var a = b\n output: Ignoring
>
> 12.input: var a = jQuery(args)\n output: jQuery is yytext syntax error, unexpected 'jQuery', expecting IGNORE
在您的lex文件中,规则:
"jQuery" {
printf("%s is yytext\n", yytext);
return *yytext;
}
当看到jQuery的输入字符串时,返回标记'j'
。由于您的野牛文件从不对令牌'j'
做任何事情,因此通常会给您带来语法错误。
您需要将JQUERY
添加到%token
声明中,并使此lex规则返回该值。
edit
通常,注释可以出现在程序中的任何位置(在任何其他两个标记之间),并且完全被忽略。因此,处理它们的最简单方法是在词法分析器中:
%x comment
%%
"/*" { BEGIN comment; }
<comment>. ;
<comment>"*/" { BEGIN 0; }
这将跳过注释(根本不返回任何标记),因此语法不必担心它们。如果您不想使用词法分析器的开始状态,则可以使用复杂的正则表达式:
"/*"([^*]|\*+[^*/])*\*+"/" ;
[我想我可以给您提供解决案例10的解决方案,但是还有更深的问题。
由于情况8为您提供了您期望的结果,所以我推断出该输入
/*comment*/
被产品认可
stmt: CS stmt CE
这是说字符串“ comment”被识别为stmt
。但是,当您在CS
和stmt
之间添加空格时,解析将失败,这就是您的情况10。您可以通过将生产代码重写为[]来对此进行修补。
stmt: CS optionalws stmt optionalws CE
但是更深层次的问题是您的解析器无法识别其他注释,例如
/* This is a remarkable remark, isn't it? */
和
/**
* This is a multi-line comment.
*/