2017-04-13 5 views
1

私は、Windows上でFLEXを使って字句解析ツールを構築しようとしています。 私は常にエラーを取得しています:yylvalをフレックスで使用する方法

"undefined reference to `yylval'"

私は次のようにすべての定義がなされたextern型アップとしてyylval宣言:

%option noyywrap 
    %{ 
     #include<stdio.h> 
     #include<stdlib.h> 
     #include "tokens.h" 
     int nline = 1; 
     int size_token_array = 100; 
     int number_of_tokens_in_array = 0; 
     int inc_token_array = 50; 
     token *token_store ; 
     extern yylval; 

    %} 
    delim [ \t] 
    delim_nl [\n] 
    ws {delim}+ 
    nl {delim_nl}+ 
    letter [a-z] 
    digit [0-9] 
    id {letter}(letter.digit)* 
    int_num (0|([+-]?([1-9]{digit}*))) 
    real_num [+-]?{digit}+(\.{digit}+) 
    rel_op ">"|"<"|"<="|">="|"=="|"!=" 
    binary_ar_op "+"|"-"|"*"|"/"|"=" 
    task_id {letter}(letter+digit)* 
    signal_id {letter}(letter+digit)* 

    %% 
    "parbegin" {create_and_store_token(TOKEN_PARBEGIN,yytext,nline); return 1;} 
    "parend" {create_and_store_token(TOKEN_PAREND,yytext,nline); return 1;} 
    "task" {create_and_store_token(TOKEN_TASK,yytext,nline); return 1;} 
    "{" {create_and_store_token('{',yytext,nline); return 1;} 
    "}" {create_and_store_token('}',yytext,nline); return 1;} 
    "begin" {create_and_store_token(TOKEN_BEGIN,yytext,nline); return 1;} 
    "end" {create_and_store_token(TOKEN_END,yytext,nline); return 1;} 
    "integer" {create_and_store_token(TOKEN_INTEGER,yytext,nline); return 1;} 
    "real" {create_and_store_token(TOKEN_REAL,yytext,nline); return 1;} 
    "||" {create_and_store_token(TOKEN_PARALLEL,yytext,nline); return 1;} 
    ";" {create_and_store_token(';',yytext,nline); return 1;} 
    "," {create_and_store_token(',',yytext,nline); return 1;} 
    "do" {create_and_store_token(TOKEN_DO,yytext,nline); return 1;} 
    "until" {create_and_store_token(TOKEN_UNTIL,yytext,nline); return 1;} 
    "od" {create_and_store_token(TOKEN_OD,yytext,nline); return 1;} 
    "send" {create_and_store_token(TOKEN_SEND,yytext,nline); return 1;} 
    "accept" {create_and_store_token(TOKEN_ACCEPT,yytext,nline); return 1;} 
    "(" {create_and_store_token('(',yytext,nline); return 1;} 
    ")" {create_and_store_token(')',yytext,nline); return 1;} 
    "<" {create_and_store_token(LT,yytext,nline); yylval=rel_op; return 1;} 
    ">" {create_and_store_token(GT,yytext,nline); yylval=rel_op; return 1;} 
    "<=" {create_and_store_token(LE,yytext,nline); yylval=rel_op; return 1;} 
    ">=" {create_and_store_token(GE,yytext,nline); yylval=rel_op; return 1;} 
    "==" {create_and_store_token(EQ,yytext,nline); yylval=rel_op; return 1;} 
    "!=" {create_and_store_token(NE,yytext,nline); yylval=rel_op; return 1;} 
    "*" {create_and_store_token('*',yytext,nline); yylval=binary_ar_op; return 1;} 
    "/" {create_and_store_token('/',yytext,nline); yylval=binary_ar_op; return 1;} 
    "+" {create_and_store_token('+',yytext,nline); yylval=binary_ar_op; return 1;} 
    "-" {create_and_store_token('-',yytext,nline); yylval=binary_ar_op; return 1;} 
    "=" {create_and_store_token('=',yytext,nline); yylval=binary_ar_op; return 1;} 
    {ws} ; 
    {nl} nline++; 
    id {create_and_store_token(TOKEN_ID,yytext,nline); return 1;} 
    int_num {create_and_store_token(TOKEN_INT_NUM,yytext,nline); return 1;} 
    real_num {create_and_store_token(TOKEN_REAL_NUM,yytext,nline); return 1;} 
    binary_ar_op {create_and_store_token(TOKEN_AR_OP,yytext,nline); return 1;} 
    "task_id" {create_and_store_token(TOKEN_TASK_ID,yytext,nline); return 1;} 
    "signal_id" {create_and_store_token(TOKEN_SIGNAL_ID,yytext,nline); return 1;} 

    %% 
    int main() 
    { 
     token_store = (token*)calloc(size_token_array,sizeof(token)); 
     free(token_store); 
     return 0; 

    } 

    void create_and_store_token(int token_type,char* token_lexeme,int line_number){ 

     token new_token; 
     new_token.ivalue = token_type; 
     new_token.lexema = token_lexeme; 
     new_token.line_number = line_number; 

     if(size_token_array == (number_of_tokens_in_array-10)){ 

      token_store = (token*)realloc(token_store,inc_token_array*sizeof(token)); 
      size_token_array+=inc_token_array; 
      number_of_tokens_in_array++; 
      token_store[number_of_tokens_in_array]= new_token; 

     } 
     else{ 
      token_store[number_of_tokens_in_array]= new_token; 
      number_of_tokens_in_array++; 

     } 
    } 

    int nextToken(){ 
     return yylex(); 
    } 

    void backToken(){ 
     token_store[number_of_tokens_in_array].ivalue = 0; 
     token_store[number_of_tokens_in_array].lexema = ""; 
     token_store[number_of_tokens_in_array].line_number = 0; 
     number_of_tokens_in_array--; 
    } 

誰もが、私はこの問題を解決する方法のアイデアを持っていますか?

答えて

1

extern yylval;は、yylvalが他の場所で定義されていることを意味します。だからあなたはそれをしなくてはなりません。

通常、yacc/bison生成パーサで定義されているため、スキャナとパーサーをリンクすると名前が解決されます。 bison/yaccを使用していない場合は、yylvalを自分で定義する必要があります。 (あなたが実際に必要な場合は、あなたのコードは、あなたが必要とするものをヒントとして与えるものではありません。)

ところで、あなたのコードには他にも多くの問題があります。特に目立つ点の1つは、スキャナが次のトークンに移動した後にポインタyytextの値を使用できないことです。 yytextが指す文字列の永続コピーが必要な場合は、独自のコピーを作成する必要があります(不要になったときにコピー用に割り当てられたメモリを解放する必要があります)。

正規表現の多くが正しくありません。マクロの使用( "定義")は中括弧で囲む必要があります。

id {create_and_store_token(TOKEN_ID,yytext,nline); return 1;} 

は期待どおりになりません。 2文字のシーケンスと一致するだけですid{id}に変更すると、 が開始されますが、idの定義も間違っています。

個人的には、マクロには値を追加しないため、マクロは使用しません。彼らはしばしば混乱を招く。たとえば、letterの定義には、小文字しか含まれていません。あなたのコードを読んでいる人にはそれほど明白ではないものがあります。文字の場合は[[: alpha:]]、小文字の場合は[[:lower:]]、文字や数字の場合は[[:alnum:]]など、Posix文字クラスを使用するほうがはるかに優れています。

関連する問題