私は、パーサーを実装するためにflexとbisonを使用しています。私が遭遇した問題は、どのようにして別々のフレックスファイルのトークンをパーサーに与えることができるかということです。 parser.tab.c
をコンパイルしようとすると約"undefined reference to yylex"
という文句があります。 次に、コンパイル時に-dオプションを設定して、ヘッダーファイルをflexファイルにインクルードしようとしました。フレックスとBisonを使用するパーサー
私はちょうどflexとbison(コンパイルと実行に関連するコマンドを使用して)の正しい手順を知りたいです。私はgccコンパイラを使用しています。たくさん
/* Token Scanner for C- language */
%{
#include <stdio.h>
#include <stdlib.h>
#include "parser.tab.h"
extern YYSTYPE yylval;
%}
digit [0-9]
letter [a-zA-Z]
NUM {digit}+
ID {letter}+
KEY_WORD else|if|int|return|void|while
PLUS_OPERATOR "+"
MINUS_OPERATOR "-"
MUL_OPERATOR "*"
DIV_OPERATOR "/"
LESS_THAN_OPERATOR "<"
LESS_THAN_OR_EQUAL_OPER "<="
GREATER_THAN_OPERATOR ">"
GREATER_THAN_OR_EQUAL_OPERATOR ">="
EQUAL_OPERATOR "="
OBJ_EQUAL_OPERATOR "=="
NOT_EQUAL_OPERATOR "!="
COMMA_SYMBOL ","
SEMI_COLON_SYMBOL ";"
LEFT_BRAC_SYMBOL "("
RIGHT_BRAC-SYMBOL ")"
LEFT_SQUARE_BRAC_SYMBOL "["
RIGHT_SQUARE_BRAC_SYMBOL "]"
LEFT_CURLY_BRAC_SYMBOL "{"
RIGHT_CURLY_BRAC_SYMBOL "}"
LEFT_COMMENT "/*"
RIGHT_COMMENT "*/"
ELSE "else"
IF "if"
INT "int"
RETURN "return"
VOID "void"
WHILE "while"
SYMBOL "+"|"-"|"*"|"/"|"<"|"<="|">"|">="|"=="|"!="|"="|";"|","|"("|")"|"{"|"}"|"["|"]"|"/*"|"*/"
WHITESPACE [ \t\n]+
COMMENT "/*"(.)*({WHITESPACE})*(.)*"*/"
ERROR1 {NUM}(({ID}|{KEY_WORD})|{NUM})+
ERROR2 {ID}(({NUM}|{KEY_WORD})|{ID})+
ERROR3 {KEY_WORD}(({ID}|{NUM})|{KEY_WORD})+
ERROR ERROR1|ERROR2|ERROR3
%%
{NUM} {
return NUM;
}
{ELSE} {
return ELSE;
}
{IF} {
return IF;
}
{INT} {
return INT;
}
{RETURN} {
return RETURN;
}
{VOID} {
return VOID;
}
{WHILE} {
return WHILE;
}
{ID} {
return ID;
}
{PLUS_OPERATOR} {
return PLUS_OPERATOR;
}
{MINUS_OPERATOR} {
return MINUS_OPERATOR;
}
{MUL_OPERATOR} {
return MUL_OPERATOR;
}
{DIV_OPERATOR} {
return DIV_OPERATOR;
}
{LESS_THAN_OPERATOR} {
return LESS_THAN_OPERATOR;
}
{LESS_THAN_OR_EQUAL_OPER} {
return LESS_THAN_OR_EQUAL_OPER;
}
{GREATER_THAN_OPERATOR} {
return GREATER_THAN_OPERATOR;
}
{GREATER_THAN_OR_EQUAL_OPERATOR} {
return GREATER_THAN_OR_EQUAL_OPERATOR;
}
{EQUAL_OPERATOR} {
return EQUAL_OPERATOR;
}
{OBJ_EQUAL_OPERATOR} {
return NOT_EQUAL_OPERATOR;
}
{NOT_EQUAL_OPERATOR} {
return NOT_EQUAL_OPERATOR;
}
{COMMA_SYMBOL} {
return COMMA_SYMBOL;
}
{SEMI_COLON_SYMBOL} {
return SEMI_COLON_SYMBOL;
}
{LEFT_BRAC_SYMBOL} {
return LEFT_BRAC_SYMBOL;
}
{RIGHT_BRAC-SYMBOL} {
return RIGHT_BRAC_SYMBOL;
}
{LEFT_SQUARE_BRAC_SYMBOL} {
return LEFT_SQUARE_BRAC_SYMBOL;
}
{RIGHT_SQUARE_BRAC_SYMBOL} {
return RIGHT_SQUARE_BRAC_SYMBOL;
}
{LEFT_CURLY_BRAC_SYMBOL} {
return LEFT_CURLY_BRAC_SYMBOL;
}
{RIGHT_CURLY_BRAC_SYMBOL} {
return RIGHT_CURLY_BRAC_SYMBOL;
}
{LEFT_COMMENT} {
return LEFT_COMMENT;
}
{RIGHT_COMMENT} {
return RIGHT_COMMENT;
}
{WHITESPACE} {
}
{ERROR} {
}
%%
main(argc, argv)
int argc;
char **argv;
{
++argv, --argc; /* skip over program name */
if (argc > 0)
yyin = fopen(argv[0], "r");
else
yyin = stdin;
yylex();
}
int yywrap(void){return 1;}
パーサありがとう
:
%{
#include <stdio.h>
#include <ctype.h>
#define YYDEBUG 1
%}
%token ID NUM PLUS_OPERATOR MINUS_OPERATOR MUL_OPERATOR DIV_OPERATOR LESS_THAN_OPERATOR LESS_THAN_OR_EQUAL_OPER GREATER_THAN_OPERATOR GREATER_THAN_OR_EQUAL_OPERATOR EQUAL_OPERATOR OBJ_EQUAL_OPERATOR NOT_EQUAL_OPERATOR COMMA_SYMBOL SEMI_COLON_SYMBOL LEFT_BRAC_SYMBOL RIGHT_BRAC_SYMBOL LEFT_SQUARE_BRAC_SYMBOL RIGHT_SQUARE_BRAC_SYMBOL LEFT_CURLY_BRAC_SYMBOL RIGHT_CURLY_BRAC_SYMBOL LEFT_COMMENT RIGHT_COMMENT ELSE IF INT RETURN VOID WHILE
%expect 1
%%
program: declaration_list
;
declaration_list: declaration_list declaration
| declaration { printf("njuwandusanduansduasdsdsdsa"); }
;
declaration : var_declaration
| fun_declaration { printf("njuwandusanduansduasdsdsdsa");}
;
var_declaration : type_specifier ID SEMI_COLON_SYMBOL
| type_specifier ID LEFT_SQUARE_BRAC_SYMBOL NUM RIGHT_SQUARE_BRAC_SYMBOL COMMA_SYMBOL { printf("njuwandusanduansduasdsdsdsa"); }
;
type_specifier : INT
| VOID { printf("njuwandusanduansduasdsdsdsa");}
;
fun_declaration : type_specifier ID LEFT_BRAC_SYMBOL params RIGHT_BRAC_SYMBOL compound_stmt
;
params : param_list
| VOID
;
param_list : param_list COMMA_SYMBOL param
| param
;
param : type_specifier ID
| type_specifier ID LEFT_SQUARE_BRAC_SYMBOL RIGHT_SQUARE_BRAC_SYMBOL
;
compound_stmt : LEFT_CURLY_BRAC_SYMBOL local_declarations statement_list RIGHT_CURLY_BRAC_SYMBOL
;
local_declarations : local_declarations var_declaration
| /* empty */
;
statement_list : statement_list statement
|/* empty */
;
statement : expression_stmt
| compound_stmt
| selection_stmt
| iteration_stmt
| return_stmt
;
expression_stmt : expression SEMI_COLON_SYMBOL
| SEMI_COLON_SYMBOL
;
selection_stmt : IF LEFT_BRAC_SYMBOL expression RIGHT_BRAC_SYMBOL statement
| IF LEFT_BRAC_SYMBOL expression RIGHT_BRAC_SYMBOL statement ELSE statement
;
iteration_stmt : WHILE LEFT_BRAC_SYMBOL expression RIGHT_BRAC_SYMBOL statement
;
return_stmt : RETURN SEMI_COLON_SYMBOL
| RETURN expression SEMI_COLON_SYMBOL
;
expression: var EQUAL_OPERATOR expression
| simple_expression
;
var : ID
| ID LEFT_SQUARE_BRAC_SYMBOL expression RIGHT_SQUARE_BRAC_SYMBOL
;
simple_expression : additive_expression relop additive_expression
| additive_expression
;
relop : LESS_THAN_OR_EQUAL_OPER
| LESS_THAN_OPERATOR
| GREATER_THAN_OPERATOR
| GREATER_THAN_OR_EQUAL_OPERATOR
| OBJ_EQUAL_OPERATOR
| NOT_EQUAL_OPERATOR
;
additive_expression : additive_expression addop term
| term
;
addop : PLUS_OPERATOR
| MINUS_OPERATOR { printf("njuwandusanduansduasdsdsdsa"); }
;
term : term mulop factor { $$ = $1 + $3; }
| factor
;
mulop : MUL_OPERATOR
| DIV_OPERATOR
;
factor : LEFT_BRAC_SYMBOL expression RIGHT_BRAC_SYMBOL
| var
| call
| NUM
;
call : ID LEFT_BRAC_SYMBOL args RIGHT_BRAC_SYMBOL
;
args : arg_list
|/* empty */
;
arg_list : arg_list COMMA_SYMBOL expression
| expression
;
%%
main()
{
extern int yydebug;
yydebug=1;
return yyparse();
}
int yyerror(char * s)
{
fprintf(stderr, "%s\n",s);
return 0;
}