0
votes

I'm implementing a programming language (katir) with the help of yacc and lex. Lex and yacc files are prepared and lex.yy.c and y.tab.c files are created without any error. But when I call gcc -o katir y.tab.c it gives a big list of error such as and it continues like this:

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);

My lex file is;

%{
#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;}

And yacc file is the following;

%{
#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;
}

And finally all the code I call in linux terminal is the following;

flex katir.l
yacc katir.yacc
gcc -o katir y.tab.c
1
Inspect the ytab.c file. There must be a syntax error before the first error reported. It will be in one of your source files. Your yacc grammar looks OK.Paul Ogilvie
Note: return yyparse(); in main means the rest of main will not be executed.Paul Ogilvie
Isn't y.tab.c an auto generated file ? I looked at it and couldn't understand how to find syntax error. If you want I can add whole error message that I get. Sorry for these newbie questions btw since I'm new in this platform and also thanks for support @PaulOgilvieÇağlar Ç.
Is it because using token names such as "boolean" mixes with C reserved word boolean since there is a call in y.tab.c as file "#define boolean 302" or there is another problem ?Çağlar Ç.
@PaulOgilvie Of course they can clash. If you have #define int 258 and #define if 259, then this will cause something like int main() to become 258 main(), which is a syntax error, and if (cond) to become 259 (cond), which is a type error. That looks to be exactly OP's problem.sepp2k

1 Answers

2
votes

As you already surmised in a comment, your problem is that your token names clash with C keywords. Defining a token if in your yacc file will cause the generated C file to contain both a line like if = 258 (where 258 could of course be a different number) inside an enum declaration and #define if 258 afterwards. if = 258 is a syntax error of course and #define if 258 will cause errors anywhere where if is used as part of an actual if statement anywhere in the following code (because something like if(cond) would become 42(cond), which is a type error). The same goes for any other keywords.

The convention is for token names to be written in ALL_CAPS to avoid exactly this problem.