0

フレックス定義:

"view"  { return VIEW;}
"cell"  { return CELL;}
[A-Za-z]+ {
      yylval.strval=strdup(yytext);
      return ALPHA;
      }
[()]   {return yytext[0];}  

私のバイソン文法:

static int len=10;
static char *allkeywords[10]=   {"view","acload","actual","after","alpha","and","annotate","apply","arc","array" };

cell:’(’ CELL ALPHA ’)’ { goal=$3;
                       flag=binary_search(allkeywords,len,goal);
                       if(flag) 
                        { 
                       yyerror("warnning: the component name is a keyword");
                       yyclearin;
                       yyerrok;
                       }                                                                    
            ;
int binary_search(const char *a[10], int len, char *goal)
  {    
   int low = 0;    
   int high = len - 1;    
   while(low <= high)    
    {        
     int middle = (low + high)/2;        
     if(strcmp (goal,a[middle])==0 )           
         return 1;        
       else if(strcmp (goal,a[middle]) < 0)        
          high = middle - 1;            
            else            
               low = middle + 1;    
 }    
 return 0;     
 }

私の指示:

bison -d -v bison.y
flex  flex.l 
gcc bison.tab.c lex.yy.c

例えば、入力ストリームは (cell view ) で、「view」という単語はユーザーが与えたランダムなモノグラムです。偶然にも EDIF ファイルのキーワードであり、ALPHA にも対応しています。ユーザーが指定した ALPHA がキーワードの場合は yyerror 関数を呼び出して警告するように設定しましたが、bison は yyerror 自体を呼び出します。その出力は、「zhouzhou:1.3-1.6:syntax error, unexpected CELL, expected EDIF」です。実際には、「zhouzhou:1.3-1.6: warnning: the component name is a keyword」となります。bison を yyerror と呼ばないようにする方法は?

4

1 に答える 1

1

キーワードを識別子として許可するように文法をコーディングすることはできますが、そうするのは不自然で、非常に困難です。キーワードは、識別子として使用できないため、そう呼ばれています。

働くflex.l

%{
#include "bison.tab.h"
%}

%%
"view"  { puts("VIEW"); return VIEW;}
"cell"  { puts("CELL"); return CELL;}
[A-Za-z]+ {
      yylval.strval=strdup(yytext);
      puts("ALPHA:");
      puts(yylval.strval);
      return ALPHA;
      }
[()]   {puts("PARENS"); return yytext[0];}  

.      { printf("SKIP: %d %c\n", yytext[0], yytext[0]); }

%%

int yywrap(void)
{
    return(1);
}

働くbison.y

%{
#include <stdio.h>
#include <string.h>

static int binary_search(char **a, int len, char *goal);

static char *goal;
static int flag;
static int len=10;
static char *allkeywords[10]=   {"view", "acload", "actual", "after", "alpha", "and", "annotate", "apply", "arc", "array" };

%}

%union { char *strval; }

%token <strval> CELL
%token <strval> ALPHA
%token <strval> VIEW

%%

cell: '(' CELL ALPHA ')'
        {
            goal=$3;
            flag=binary_search(allkeywords, len, goal);
            if(flag) 
            { 
                printf("Before yyerror()\n");
                yyerror("warning: the component name is a keyword");
                printf("After yyerror()\nBefore yyclearin\n");
                yyclearin;
                printf("After yyclearin\nBefore yyerrok\n");
                yyerrok;
                printf("After yyerrok\n");
            }                                                                    
        }
    ;

%%

static int binary_search(char **a, int len, char *goal)
{    
    int low = 0;    
    int high = len - 1;    
    while(low <= high)    
    {        
        int middle = (low + high)/2;        
        if(strcmp (goal, a[middle])==0 )           
            return 1;        
        else if(strcmp (goal, a[middle]) < 0)        
            high = middle - 1;            
        else            
            low = middle + 1;    
    }    
    return 0;     
}

int main(void)
{
    int rc;
    yydebug = 1;
    setvbuf(stdout, 0, _IOLBF, 0);
    rc = yyparse();
    printf("== In main after yyparse() = %d\n", rc);
    return(0);
}

Mac OS X 10.8.2 用のビルド スクリプト

set -x
bison -d -v bison.y &&
flex  flex.l  &&
gcc -DYYDEBUG bison.tab.c lex.yy.c -ly &&

a.out < data

データファイル

(cell alpha)

実行中のプログラムからのトレース

++ bison -d -v bison.y
++ flex flex.l
++ gcc -DYYDEBUG bison.tab.c lex.yy.c -ly
++ a.out
Starting parse
Entering state 0
Reading a token: PARENS
Next token is token '(' ()
Shifting token '(' ()
Entering state 1
Reading a token: CELL
Next token is token CELL ()
Shifting token CELL ()
Entering state 4
Reading a token: SKIP: 32  
ALPHA:
alpha
Next token is token ALPHA ()
Shifting token ALPHA ()
Entering state 6
Reading a token: PARENS
Next token is token ')' ()
Shifting token ')' ()
Entering state 7
Reducing stack by rule 3 (line 29):
   $1 = token '(' ()
   $2 = token CELL ()
   $3 = token ALPHA ()
   $4 = token ')' ()
Before yyerror()
warning: the component name is a keyword
After yyerror()
Before yyclearin
After yyclearin
Before yyerrok
After yyerrok
-> $$ = nterm cell ()
Stack now 0
Entering state 3
Reducing stack by rule 2 (line 25):
   $1 = nterm cell ()
Stack now 0
== In main after yyparse() = 0

コードが一度関数に正常に戻り、 をmain()呼び出さないことに注意してくださいyyerror()

于 2013-03-02T04:19:01.957 に答える