1

以下のコードでどこが間違っていたのかを見つけようとしています。

フレックス入力:

%{
        #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
4

2 に答える 2

0

あなたのlexファイルでは、ルール:

"jQuery"        {
                printf("%s is yytext\n", yytext);
                return *yytext;
                }

'j'jQueryの入力文字列を見るとトークンを返します。bison ファイルはトークンに対して何もしないため、'j'通常は構文エラーが発生します。

宣言に追加JQUERYし、この lex ルールがそれを返すようにする必要があります。%token

編集

通常、コメントはプログラム内の任意の場所 (他の 2 つのトークンの間) に表示され、完全に無視されます。したがって、それらを処理する最も簡単な方法は、レクサーを使用することです。

%x comment
%%
"/*"           { BEGIN comment; }
<comment>.     ;
<comment>"*/"  { BEGIN 0; }

これはコメントをスキップする (トークンをまったく返さない) ため、文法はコメントを気にする必要がありません。lexer の開始状態を使用したくない場合は、代わりに複雑な正規表現を使用できます。

"/*"([^*]|\*+[^*/])*\*+"/"          ;
于 2012-08-01T20:47:21.440 に答える
0

ケース 10 を解決する修正を提供できると思いますが、もっと深い問題があります。

ケース 8 では期待どおりの結果が得られるため、入力は

/*comment*/

誇りに思っています

stmt: CS stmt CE

つまり、文字列 "comment" は として認識されますstmt。しかし、間に空白を追加するCSstmt、解析が失敗します。これはケース10です。プロダクションを次のように書き直すことで、これにパッチを当てることができます

stmt: CS optionalws stmt optionalws CE

しかし、より深刻な問題は、パーサーが他のコメントを認識できないことです。

/* This is a remarkable remark, isn't it? */ 

/**
 * This is a multi-line comment.
 */
于 2012-08-03T15:18:42.957 に答える