我正在嘗試使用flex/bison
作爲練習來製作一個簡單的玩具(LET
)語言。不過,我不斷收到以下錯誤,當我運行命令g++ -Wall -std=c++11 repl.cpp -v -o LET
:架構x86_64 flex/bison的未定義符號
Undefined symbols for architecture x86_64:
"yy_scan_string(char const*)", referenced from:
_main in repl-030403.o
"yy_delete_buffer(yy_buffer_state*)", referenced from:
_main in repl-030403.o
"yyparse()", referenced from:
_main in repl-030403.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
我已經定義了以下文件,
LET.y
:
%{
#include <iostream>
#include <cstdio>
#include <string>
#include "AST.hpp"
#include "GENERATED_CODE/LET_parser.hpp"
#include "GENERATED_CODE/LET_lexer.hpp"
using namespace std;
extern int yylex();
extern char* yytext;
extern int yyparse();
extern Pgm* prog;
void yyerror (char const *s) {
fprintf (stderr, "%s\n", s);
}
%}
%output "./PARSER/GENERATED_CODE/LET_parser.cpp"
%defines "./PARSER/GENERATED_CODE/LET_parser.hpp"
%union {
Pgm* prog;
int value;
char* var;
char cval;
Exp* exp;
string* str;
}
%token TTRUE
%token TFALSE
%token TLET
%token TIN
%token TIF
%token TTHEN
%token TELSE
%token TISZERO
%token TASSIGN
%token TLPAREN
%token TRPAREN
%token TPLUS
%token TMINU
%token TMULT
%token TDIVI
%token TREMI
%token TCOMMA
%token <value> TNUM
%token <var> TVAR
%type <prog> Prog
%type <exp> Exp
%type <str> Vari
/* Causes Bison to give more detailed error messages when parsing */
%error-verbose
%%
/* Bison Grammar Declarations */
Prog: Exp { prog = new Pgm($1); }
Vari: TVAR { $$ = new string(yytext);}
Exp: TNUM { $$ = new ConstExp(atoi(yytext)); }
| TVAR { $$ = new VarExp(yytext); }
| TTRUE { $$ = new TrueExp; }
| TFALSE { $$ = new FalseExp; }
| TISZERO TLPAREN Exp TRPAREN { $$ = new IsZeroExp($3); }
| TMINU TLPAREN Exp TCOMMA Exp TRPAREN { $$ = new DiffExp($3, $5); }
| TPLUS TLPAREN Exp TCOMMA Exp TRPAREN { $$ = new SumExp($3, $5); }
| TMULT TLPAREN Exp TCOMMA Exp TRPAREN { $$ = new MultExp($3, $5); }
| TDIVI TLPAREN Exp TCOMMA Exp TRPAREN { $$ = new QuotExp($3, $5); }
| TREMI TLPAREN Exp TCOMMA Exp TRPAREN { $$ = new RemiExp($3, $5); }
| TIF Exp TTHEN Exp TELSE Exp { $$ = new IfExp($2, $4, $6); }
| TLET Vari TASSIGN Exp TIN Exp { $$ = new LetExp(*$2, $4, $6); }
LET.l
:
%{
#include <iostream>
#include <cstdio>
#include "AST.hpp"
#include "GENERATED_CODE/LET_parser.hpp"
using namespace std;
int yylex();
void yyerror (char const *s) {
fprintf (stderr, "%s\n", s);
}
%}
%option c++
%option header-file = "./PARSER/GENERATED_CODE/LET_lexer.hpp"
%option outfile = "./PARSER/GENERATED_CODE/LET_lexer.cpp"
%option noyywrap
digit [0-9]
alpha [a-zA-Z]
ws [ \t\n]+
%%
"#".*[\n] { /* No Action Taken */ }
{ws} { /* No Action Taken */ }
"true" { return TTRUE; }
"false" { return TFALSE; }
"let" { return TLET; }
"in" { return TIN; }
"if" { return TIF; }
"then" { return TTHEN; }
"else" { return TELSE; }
"zero?" { return TISZERO; }
"=" { return TASSIGN; }
"(" { return TLPAREN; }
")" { return TRPAREN; }
"+" { return TPLUS; }
"-" { return TMINU; }
"*" { return TMULT; }
"/" { return TDIVI; }
"%" { return TREMI; }
"," { return TCOMMA; }
"-"?{digit}+ { return TNUM; }
[a-zA-Z][a-z|0-9|\_|\'|\-|\?]* { return TVAR; }
Makefile
:
generate-parser: clean flex bison
clean:
rm -rf PARSER/GENERATED_CODE
mkdir -p PARSER/GENERATED_CODE
flex:
flex PARSER/LET.l
bison:
bison -d PARSER/LET.y
repl.cpp
:
#include <cstdio>
#include "./PARSER/AST.hpp"
#include "./PARSER/GENERATED_CODE/LET_parser.hpp"
#include "./PARSER/GENERATED_CODE/LET_lexer.hpp"
using namespace std;
extern YY_BUFFER_STATE yy_scan_string(const char * str);
extern void yy_delete_buffer(YY_BUFFER_STATE buffer);
int main() {
char input[] = "RAINBOW UNICORN 1234 UNICORN";
YY_BUFFER_STATE state = yy_scan_string(input);
yyparse();
yy_delete_buffer(state);
return 0;
}
[Can not compile flex&bison(Symbols not found x86 \ _64)]可能的重複](http://stackoverflow.com/questions/28207339/cant-compile-flex-bison-symbols-not-found- x86-64) –