2013-03-15 81 views
2

當我嘗試在yyerror函數中打印行號時,出現錯誤。我正在開發OSX。Flex Bison:Building C編譯器 - 錯誤消息中的行號

(在compiler.l行號)

%{ 

#include "compiler.tab.h" 
int lineNumber = 1; 

%} 
%% 

int { return INT; } 
float { return FLOAT; } 
void { return VOID; } 
do { return DO; } 
while { return WHILE; } 
if { return IF; } 
return { return RETURN; } 
else { return ELSE; } 
\/\/(.)* { return COMMENT; } 
\/\*(.)*\*\/ { return COMMENT; } 
[a-zA-Z][a-zA-Z0-9_]* { return IDENT; } 
[0-9]+\.[0-9]+ { sscanf(yytext, "%lf", &yylval.reell); return FVAL; } 
[0-9]+ { yylval.integer = atoi(yytext); return IVAL; } 
\({ return OPA; } 
\) { return CPA; } 
\{ { return OB; } 
\} { return CP; } 
\; { return SEMICOLON; } 
\, { return COMMA; } 
\! { return NOT; } 
\-\- { return DECREMENT; } 
\+\+ { return INCREMENT; } 
\<\< { return LSHIFT; } 
\=\= { return EQUALS; } 
\<\= { return LTOE; } 
\>\= { return GTOE; } 
\&\& { return AND; } 
\|\| { return OR; } 
\= { return ASSIGNMENT; } 
\< { return LT; } 
\> { return GT; } 
\/ { return DIVIDE; } 
\* { return MULTIPLY; } 
\+ { return PLUS; } 
\- { return MINUS; } 
[ ]+ { return BLNK; } 
[\n]* { ++lineNumber; return NL; } 

%% 

compiler.c

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include "compiler.h" 

extern int lineNumber; 

int main (void) 
{ 
    yyparse(); 
    return 0; 
} 

void yyerror(char * str) 
{ 
    fprintf(stderr, "Error: %s, Line %d\n", str, lineNumber); 
} 

我得到以下錯誤消息:架構x86_64的

未定義符號:「_lineNumber 「,編號爲 ,來自: 編譯器中的_yyerror ld:未找到符號(s)民族形式x86_64的collect2:LD返回1退出狀態

這是命令(shell文件),我用它來編譯:

#!/bin/bash 

flex compiler.l 
bison -d compiler.y 

gcc -g -c compiler.tab.c -o compiler_y.o 
gcc -g -Wall -std=c99 -c lex.yy.c 
gcc -g -c compiler.tab.c -o compiler_y.o 

gcc -g -Wall -std=c99 -c compiler.c 
gcc -g -o compiler compiler.o compiler_y.o lex.yy.o -lm -lfl 
+0

標記時請小心。 Flex用於Apache/Adob​​e UI框架。 Gnu-flex用於詞法分析器。 – JeffryHouser 2013-03-15 10:25:23

+0

你在'.l'文件中放置了那行嗎?看起來好像你並沒有將它定義爲外部符號(或者,如果你是,你沒有在你的可執行文件中包含編譯的詞法分析器)。 – rici 2013-03-15 18:35:15

+0

@rici我放了compiler.l的整個代碼。希望這可以幫助。感謝你的幫助。 – hapablap 2013-03-15 21:15:06

回答

6

您可以在Flex源使用%option yylineno然後變量int yylineno會給當前令牌的行號。注意不要在語法中使用yylineno(bison/yacc),因爲標記器一般在解析器之前。如果您想在解析器中使用行號,通常將行號附加到標記,以便解析器可以通過標記進行訪問。

錯誤消息很可能是由於在compiler.tab.o中沒有鏈接導致的,從compiler.l獲得,通過在其上運行flex,然後通過C編譯器傳遞它。