Lex & Yacc:gcc 在编译时 y.tab.c 给出了许多预期的标记错误
Lex & Yacc: gcc while compiling y.tab.c gives many expected token errors
我正在 yacc 和 lex 的帮助下实现一种编程语言 (katir)。准备了 Lex 和 yacc 文件,并且创建了 lex.yy.c 和 y.tab.c 文件,没有任何错误。但是当我调用 gcc -o katir y.tab.c 时,它给出了一大堆错误,并且它继续这样:
y.tab.c:557:41: error: expected ‘;’ before ‘goto’
yyloop:
^
y.tab.c:558:8: error: called object is not a function or function pointer
if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
^
y.tab.c:559:5: error: expected ‘;’ before ‘{’ token
if (yychar < 0)
^
y.tab.c:607:8: error: called object is not a function or function pointer
yyinrecovery:
^
y.tab.c:608:5: error: expected ‘;’ before ‘{’ token
if (yyerrflag < 3)
^
y.tab.c:666:8: error: called object is not a function or function pointer
yym = yylen[yyn];
^
y.tab.c:667:9: error: expected ‘;’ before ‘yyval’
if (yym)
^
y.tab.c:669:9: error: expected ‘;’ before ‘memset’
else
^
y.tab.c:677:8: error: called object is not a function or function pointer
yym = yylhs[yyn];
^
y.tab.c:678:5: error: expected ‘;’ before ‘{’ token
if (yystate == 0 && yym == 0)
^
y.tab.c:708:9: error: expected ‘;’ before ‘yystate’
else
^
y.tab.c:714:8: error: called object is not a function or function pointer
#endif
^
y.tab.c:715:5: error: expected ‘;’ before ‘{’ token
if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack))
^
y.tab.c:727:12: error: called object is not a function or function pointer
yyfreestack(&yystack);
^
y.tab.c:731:12: error: called object is not a function or function pointer
yyfreestack(&yystack);
我的 lex 文件是;
%{
#include <stdlib.h>
void yyerror(char *);
%}
begin begin
end end
assignment_op <-
endline \n
difference diff
set_type set
integer_type integer
char_type char
boolean_type boolean
string_type string
float_type float
constant const
equal ==|eq
comment {hashtag}([^\n])*\n
hashtag #
and \&\&|and
or \|\||or
cardinality_op \|
cp_op cp
set_del del
else else
not !|not
lt <|lt
gt >|gt
lte <=|lte
gte >=|gte
lp \(
rp \)
lcb \{
rcb \}
comma ,
endstmnt \;
underscore _
dot \.
digit [0-9]
letter[a-zA-Z]
if if
then then
do do
multiplier \*
divider \/
subtractor \-
adder \+
union uni
intersection inter
subset subs
superset sups
while while
for for
fc fc
return return
input input
output output
true true
false false
space ([ ])
boolean TRUE|FALSE
integer [+-]?({digit})+
float ({integer})*(\.({digit})+|({digit})+\.)({digit})*
char \'[^\\']\'
string \"([^\\"]|\\"|\\n|\\)*\"
identifier {letter}({letter}|{digit}|{underscore})*
text ([^\\"]|\\"|\\n|\\)*
whitespace [ \t]
%option yylineno
%%
{end} return end;
{begin} return begin;
{assignment_op} return assignment_op;
{equal} return equality_op;
{hashtag} return hashtag;
{set_type} return set_type;
{and} return and;
{or} return or;
{else} return else;
{lp} return lp;
{rp} return rp;
{lcb} return lb;
{rcb} return rb;
{lt} return lt;
{gt} return gt;
{lte} return lte;
{gte} return gte;
{comma} return comma;
{dot} return dot;
{then} return then;
{cardinality_op} return cardinality_op;
{cp_op} return cp_op;
{set_del} return del;
{float} return float;
{digit} return digit;
{integer} return integer;
{integer_type} return int_type;
{char_type} return char_type;
{boolean_type} return boolean_type;
{string_type} return string_type;
{float_type} return float_type;
{if} return if;
{do} return do;
{while} return while;
{for} return for;
{true} return true;
{false} return false;
{difference} return difference;
{union} return union;
{intersection} return intersection;
{subset} return subset;
{superset} return superset;
{constant} return constant;
{boolean} return boolean;
{char} return char;
{fc} return fc;
{endline} ;
{whitespace};
{return} return return;
{output} return output;
{input} return input;
{string} return string;
{identifier} return identifier;
{comment} return comment;
{endstmnt} return endstmnt;
{underscore} return underscore;
{multiplier} return multiplier;
{divider} return divider;
{subtractor} return subtractor;
{adder} return adder;
{text} return text;
%%
int yywrap(){return 1;}
yacc文件如下;
%{
#include <stdio.h>
#include <stdlib.h>
%}
%token begin
%token end
%token assignment_op
%token equal
%token hashtag
%token constant
%token and
%token or
%token then
%token not
%token else
%token lp
%token rp
%token lcb
%token rcb
%token comment
%token lt
%token gt
%token lte
%token gte
%token comma
%token dot
%token cardinality_op
%token cp_op
%token set_del
%token float
%token digit
%token integer
%token integer_type
%token char_type
%token boolean_type
%token string_type
%token float_type
%token if
%token do
%token while
%token for
%token true
%token false
%token difference
%token union
%token set_type
%token intersection
%token subset
%token superset
%token constant
%token boolean
%token char
%token fc
%token return
%token output
%token input
%token string
%token identifier
%token comment
%token endstmnt
%token underscore
%token multiplier
%token divider
%token subtractor
%token adder
%token text
%start program
%right assignment_op
%left adder subtractor difference intersection union
%left multiplier divider
%left cp_op
%%
//Start Rule
program:
begin stmnt_l end;
stmnt_l:
stmnt endstmnt
|stmnt endstmnt stmnt_l
;
//Possible statement types
stmnt:
if_stmnt;
nan_if:
loop_stmnt
|expression
|declare
|initialize
|in_out_stmnt
|function
;
loop_stmnt:
while_stmnt
|for_stmnt
|do_while_stmnt
;
if_stmnt: matched | unmatched;
matched: if logical_expression then matched else matched| nan_if;
unmatched: if logical_expression then stmnt
| if logical_expression then matched else unmatched;
while_stmnt: while lp logical_expression rp lcb stmnt_l rcb;
do_while_stmnt: do lcb stmnt_l rcb while logical_expression ;
for_stmnt: for lp initialize endstmnt logical_expression lp stmnt_l rp;
term: var | constant_type | function_call;
constant_type: constant var;
var: identifier;
//Types
type: boolean | string | integer | float; //|set
primitive: boolean_type | string_type | integer_type | float_type | set_type;
set: lcb list rcb | lcb rcb;
list: type | var | type comma list | var comma list;
//----------------------------------Declerations----------------------------------------------
declare:
primitive var;
init_types:
type | function_call | set_exp;
initialize:
declare assignment_op init_types | var assignment_op init_types;
//Connectives
logical_operator: subset | superset | lt | gt | and | or | not | equal;
logical_expression: term logical_operator logical_expression | term logical_operator term | not_expression;
not_expression: not lp logical_expression rp;
del_expression: set_del var;
//Arithmetic
arithmetic_expression: arithmetic_expression adder arithmetic_expression | exp2;
exp2: exp2 subtractor exp2 | exp3;
exp3: exp3 multiplier exp3 | exp4;
exp4: exp4 divider exp4 | exp5;
exp5: integer | float | function_call;
//Set Expressions
set_exp: exp_uni;
exp_uni: exp_uni union exp_uni | exp_intersection;
exp_intersection: exp_intersection intersection exp_intersection| exp_diff;
exp_diff: exp_diff difference exp_diff|exp_cartesian;
exp_cartesian: exp_cartesian cp_op exp_cartesian | set;
expression: arithmetic_expression | logical_expression | cardinality_expression | del_expression;
cardinality_expression: cardinality_op var cardinality_op | cardinality_op set cardinality_op;
//Input/Output
in_out_stmnt: input_stmnt | output_stmnt;
input_stmnt: input lp input_body rp;
input_body: type var;
output_stmnt: output lp output_body rp;
output_body: var;
//Function
function: type var lp arguments rp lcb stmnt_l return_stmnt rcb
| type var lp rp lcb stmnt_l return_stmnt rcb;
arguments: primitive var | primitive var comma arguments;
function_call: fc lp parameters rp | fc lp rp;
parameters: var | var comma parameters |type comma parameters;
return_stmnt: return var;
%%
#include "lex.yy.c"
int yyerror(char *s) {
fprintf(stdout, "line %d: %s\n", yylineno,s);
}
int main(){
return yyparse();
if(yynerrs < 1){
printf("Parsing is successful\n");
}
return 0;
}
最后,我在 linux 终端中调用的所有代码如下;
flex katir.l
yacc katir.yacc
gcc -o katir y.tab.c
正如您已经在评论中推测的那样,您的问题是您的令牌名称与 C 关键字冲突。在 yacc 文件中定义标记 if
将导致生成的 C 文件在 enum
声明中包含像 if = 258
这样的行(其中 258 当然可以是不同的数字)和 #define if 258
之后。 if = 258
当然是一个语法错误, #define if 258
会在以下代码中任何地方 if
用作实际 if
语句的任何地方引起错误(因为像 if(cond)
会变成 42(cond)
,这是一个类型错误)。任何其他关键字也是如此。
惯例是将令牌名称写入 ALL_CAPS 以避免这个问题。
我正在 yacc 和 lex 的帮助下实现一种编程语言 (katir)。准备了 Lex 和 yacc 文件,并且创建了 lex.yy.c 和 y.tab.c 文件,没有任何错误。但是当我调用 gcc -o katir y.tab.c 时,它给出了一大堆错误,并且它继续这样:
y.tab.c:557:41: error: expected ‘;’ before ‘goto’
yyloop:
^
y.tab.c:558:8: error: called object is not a function or function pointer
if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
^
y.tab.c:559:5: error: expected ‘;’ before ‘{’ token
if (yychar < 0)
^
y.tab.c:607:8: error: called object is not a function or function pointer
yyinrecovery:
^
y.tab.c:608:5: error: expected ‘;’ before ‘{’ token
if (yyerrflag < 3)
^
y.tab.c:666:8: error: called object is not a function or function pointer
yym = yylen[yyn];
^
y.tab.c:667:9: error: expected ‘;’ before ‘yyval’
if (yym)
^
y.tab.c:669:9: error: expected ‘;’ before ‘memset’
else
^
y.tab.c:677:8: error: called object is not a function or function pointer
yym = yylhs[yyn];
^
y.tab.c:678:5: error: expected ‘;’ before ‘{’ token
if (yystate == 0 && yym == 0)
^
y.tab.c:708:9: error: expected ‘;’ before ‘yystate’
else
^
y.tab.c:714:8: error: called object is not a function or function pointer
#endif
^
y.tab.c:715:5: error: expected ‘;’ before ‘{’ token
if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack))
^
y.tab.c:727:12: error: called object is not a function or function pointer
yyfreestack(&yystack);
^
y.tab.c:731:12: error: called object is not a function or function pointer
yyfreestack(&yystack);
我的 lex 文件是;
%{
#include <stdlib.h>
void yyerror(char *);
%}
begin begin
end end
assignment_op <-
endline \n
difference diff
set_type set
integer_type integer
char_type char
boolean_type boolean
string_type string
float_type float
constant const
equal ==|eq
comment {hashtag}([^\n])*\n
hashtag #
and \&\&|and
or \|\||or
cardinality_op \|
cp_op cp
set_del del
else else
not !|not
lt <|lt
gt >|gt
lte <=|lte
gte >=|gte
lp \(
rp \)
lcb \{
rcb \}
comma ,
endstmnt \;
underscore _
dot \.
digit [0-9]
letter[a-zA-Z]
if if
then then
do do
multiplier \*
divider \/
subtractor \-
adder \+
union uni
intersection inter
subset subs
superset sups
while while
for for
fc fc
return return
input input
output output
true true
false false
space ([ ])
boolean TRUE|FALSE
integer [+-]?({digit})+
float ({integer})*(\.({digit})+|({digit})+\.)({digit})*
char \'[^\\']\'
string \"([^\\"]|\\"|\\n|\\)*\"
identifier {letter}({letter}|{digit}|{underscore})*
text ([^\\"]|\\"|\\n|\\)*
whitespace [ \t]
%option yylineno
%%
{end} return end;
{begin} return begin;
{assignment_op} return assignment_op;
{equal} return equality_op;
{hashtag} return hashtag;
{set_type} return set_type;
{and} return and;
{or} return or;
{else} return else;
{lp} return lp;
{rp} return rp;
{lcb} return lb;
{rcb} return rb;
{lt} return lt;
{gt} return gt;
{lte} return lte;
{gte} return gte;
{comma} return comma;
{dot} return dot;
{then} return then;
{cardinality_op} return cardinality_op;
{cp_op} return cp_op;
{set_del} return del;
{float} return float;
{digit} return digit;
{integer} return integer;
{integer_type} return int_type;
{char_type} return char_type;
{boolean_type} return boolean_type;
{string_type} return string_type;
{float_type} return float_type;
{if} return if;
{do} return do;
{while} return while;
{for} return for;
{true} return true;
{false} return false;
{difference} return difference;
{union} return union;
{intersection} return intersection;
{subset} return subset;
{superset} return superset;
{constant} return constant;
{boolean} return boolean;
{char} return char;
{fc} return fc;
{endline} ;
{whitespace};
{return} return return;
{output} return output;
{input} return input;
{string} return string;
{identifier} return identifier;
{comment} return comment;
{endstmnt} return endstmnt;
{underscore} return underscore;
{multiplier} return multiplier;
{divider} return divider;
{subtractor} return subtractor;
{adder} return adder;
{text} return text;
%%
int yywrap(){return 1;}
yacc文件如下;
%{
#include <stdio.h>
#include <stdlib.h>
%}
%token begin
%token end
%token assignment_op
%token equal
%token hashtag
%token constant
%token and
%token or
%token then
%token not
%token else
%token lp
%token rp
%token lcb
%token rcb
%token comment
%token lt
%token gt
%token lte
%token gte
%token comma
%token dot
%token cardinality_op
%token cp_op
%token set_del
%token float
%token digit
%token integer
%token integer_type
%token char_type
%token boolean_type
%token string_type
%token float_type
%token if
%token do
%token while
%token for
%token true
%token false
%token difference
%token union
%token set_type
%token intersection
%token subset
%token superset
%token constant
%token boolean
%token char
%token fc
%token return
%token output
%token input
%token string
%token identifier
%token comment
%token endstmnt
%token underscore
%token multiplier
%token divider
%token subtractor
%token adder
%token text
%start program
%right assignment_op
%left adder subtractor difference intersection union
%left multiplier divider
%left cp_op
%%
//Start Rule
program:
begin stmnt_l end;
stmnt_l:
stmnt endstmnt
|stmnt endstmnt stmnt_l
;
//Possible statement types
stmnt:
if_stmnt;
nan_if:
loop_stmnt
|expression
|declare
|initialize
|in_out_stmnt
|function
;
loop_stmnt:
while_stmnt
|for_stmnt
|do_while_stmnt
;
if_stmnt: matched | unmatched;
matched: if logical_expression then matched else matched| nan_if;
unmatched: if logical_expression then stmnt
| if logical_expression then matched else unmatched;
while_stmnt: while lp logical_expression rp lcb stmnt_l rcb;
do_while_stmnt: do lcb stmnt_l rcb while logical_expression ;
for_stmnt: for lp initialize endstmnt logical_expression lp stmnt_l rp;
term: var | constant_type | function_call;
constant_type: constant var;
var: identifier;
//Types
type: boolean | string | integer | float; //|set
primitive: boolean_type | string_type | integer_type | float_type | set_type;
set: lcb list rcb | lcb rcb;
list: type | var | type comma list | var comma list;
//----------------------------------Declerations----------------------------------------------
declare:
primitive var;
init_types:
type | function_call | set_exp;
initialize:
declare assignment_op init_types | var assignment_op init_types;
//Connectives
logical_operator: subset | superset | lt | gt | and | or | not | equal;
logical_expression: term logical_operator logical_expression | term logical_operator term | not_expression;
not_expression: not lp logical_expression rp;
del_expression: set_del var;
//Arithmetic
arithmetic_expression: arithmetic_expression adder arithmetic_expression | exp2;
exp2: exp2 subtractor exp2 | exp3;
exp3: exp3 multiplier exp3 | exp4;
exp4: exp4 divider exp4 | exp5;
exp5: integer | float | function_call;
//Set Expressions
set_exp: exp_uni;
exp_uni: exp_uni union exp_uni | exp_intersection;
exp_intersection: exp_intersection intersection exp_intersection| exp_diff;
exp_diff: exp_diff difference exp_diff|exp_cartesian;
exp_cartesian: exp_cartesian cp_op exp_cartesian | set;
expression: arithmetic_expression | logical_expression | cardinality_expression | del_expression;
cardinality_expression: cardinality_op var cardinality_op | cardinality_op set cardinality_op;
//Input/Output
in_out_stmnt: input_stmnt | output_stmnt;
input_stmnt: input lp input_body rp;
input_body: type var;
output_stmnt: output lp output_body rp;
output_body: var;
//Function
function: type var lp arguments rp lcb stmnt_l return_stmnt rcb
| type var lp rp lcb stmnt_l return_stmnt rcb;
arguments: primitive var | primitive var comma arguments;
function_call: fc lp parameters rp | fc lp rp;
parameters: var | var comma parameters |type comma parameters;
return_stmnt: return var;
%%
#include "lex.yy.c"
int yyerror(char *s) {
fprintf(stdout, "line %d: %s\n", yylineno,s);
}
int main(){
return yyparse();
if(yynerrs < 1){
printf("Parsing is successful\n");
}
return 0;
}
最后,我在 linux 终端中调用的所有代码如下;
flex katir.l
yacc katir.yacc
gcc -o katir y.tab.c
正如您已经在评论中推测的那样,您的问题是您的令牌名称与 C 关键字冲突。在 yacc 文件中定义标记 if
将导致生成的 C 文件在 enum
声明中包含像 if = 258
这样的行(其中 258 当然可以是不同的数字)和 #define if 258
之后。 if = 258
当然是一个语法错误, #define if 258
会在以下代码中任何地方 if
用作实际 if
语句的任何地方引起错误(因为像 if(cond)
会变成 42(cond)
,这是一个类型错误)。任何其他关键字也是如此。
惯例是将令牌名称写入 ALL_CAPS 以避免这个问题。