0

I am new working with a compiler in C, but a I having error and I don't know where it comes from.

I think there's no problem in my Lex part of the compiler. All gramatical rules are properly printed but I still get a syntax error printed twice:

Why in the last two lines I get in the result file this:

yyerror :syntax error
yyerror :syntax error

Here is the new document I wanna analyze syntactically:

Program Test_2;

Variables
    GlobalReal : Real;
    GlobalInt  : Integer;
    GlobalString : String;
    GlobalIntVector : Integer[250];
    GlobalIntMatrix : Integer[256, 256];    
EndVars

Procedures

    Procedure FooDummyProc();
    
    NoVariables
    EndVars
    
    NoProcedures
    EndProcs
    
    Begin
    ;
    End;

    Procedure FooProcess_1(fooPar1 : Integer);
    
    Variables 
        LoopIndex : Integer;
        ProcMsg   : String; 
    EndVars
    
    NoProcedures
    EndProcs
    
    Begin 
        For LoopIndex := 1 to fooPar Do     
            Write("Im executing the ith Iteration");
        
        Write("I'm Done!!!!")
    
    End;
    
    
    Procedure FooAssign(fooPar2 : Real);
    
    Variables
        FooValue : Real;
    EndVars
    
    NoProcedures
    EndProcs
    
    Begin 
        FooValue := fooPar2;
        GlobalIntVector[FooValue] := 4;
        A := A/(FooValue + fooPar2) * 2;
        B := GlobalIntMatrix[FooValue, FooValue]        
    End;
    
    Procedure FooConditional(fooPar3 : String);
    
    Variables
        FooValue : Integer;
    EndVars
    
    NoProcedures
    EndProcs
    
    Begin
        If A = FooValue Then 
            Write("The condition is true")
        Else 
            Read (FooValue);
            
        If B = 2 Then
            Write ("This branch is also true")
        Else
            If B > 2 Then 
                Read(B)
            Else
                Read(C);
        
        If B <> 3 Then 
            Write("This is the last comparison")
        Else 
            Write(C);
        
        If C = 4 Then 
            C := 3.456
        Else        
            D := 3.8787;
        
        C := 2*Foo(34,15)
        
    
    End 
    

EndProcs;

{ No main Begin-End block }

And here is my parser

%{
    #include <stdio.h>
    
    int yylex();
    int yyerror(char *s);

%}


%token  _LBRACK 1
%token  _RBRACK 2
%token  _LPAREN 3
%token  _RPAREN 4
%token  _SEMI 5
%token  _COLON 6
%token  _COMMA 7
%token  _ASSIGN 8
%token  _PLUS 9
%token  _MINUS 10
%token  _MULT 11
%token  _DIVIDE 12
%token  _EQL 13
%token  _LESS 14
%token  _GTR 15
%token  _LEQ 16
%token  _GEQ 17
%token  _NEQ 18
%token _BEGIN 30
%token _PROGRAM 19
%token _ENDVARS 20
%token _ENDPROCS 21
%token _VARS 22
%token _NOVARS 23
%token _INTEGER 24
%token _REAL 25
%token _STRING 26
%token _PROCS 27
%token _NOPROCS 28
%token _PROC 29
%token _END 31
%token _FOR 32
%token _TO 33
%token _DO 34
%token _IF 35
%token _THEN 36
%token _ELSE 37
%token _READ 38
%token _WRITE 39
%token _ID 40
%token _ECONST 41
%token _ICONST 42
%token _RCONST 43
%token _LITERAL 44
%token _COMEN 45

%start program

%%

    program:
        title _SEMI block   {printf("Rule in program: _SEMI \n");}
    ;

    title:
        _PROGRAM _ID    {printf("Rule in title: _PROGRAM _ID \n");}
    ;

    block:
        vars _ENDVARS procs _ENDPROCS code  {printf("Rule in title: _PROGRAM _ID \n");}
    ;

    vars:
        _VARS varlist _SEMI     {printf("Rule in vars: _VARS varlist _SEMI \n");}
        | _NOVARS   {printf("Rule in vars: _NOVARS");}
    ;

    varlist:
        varlist _SEMI vardef    {printf("Rule in varlist: varlist _SEMI vardef \n");}
        | vardef    {printf("Rule in varlist: _vardef");}
    ;

    bnl:
        _LBRACK nlist _RBRACK   {printf("Rule in bnl: _LBRACK nlist _RBRACK \n");}
    ;

    vardef:
        _ID _COLON _INTEGER     {printf("Rule in vardef: _ID _COLON _INTEGER \n");} 
        | _ID _COLON _REAL      {printf("Rule in vardef: _ID _COLON _REAL \n");}
        | _ID _COLON _INTEGER bnl   {printf("Rule in vardef: _ID _COLON _INTEGER bnl \n");}
        | _ID _COLON _STRING    {printf("Rule in vardef: _ID _COLON _STRING \n");}
    ;
    
    nlist:
        nlist _COMMA _ICONST    {printf("Rule in nlist: nlist _COMMA _ICONST \n");}
        | _ICONST       {printf("Rule in nlist: _ICONST \n");}
    ;

    procs:
        _PROCS proclist     {printf("Rule in procs: _PROCS proclist \n ");}
        | _NOPROCS          {printf("Rule in procs: _NOPROCS \n");}
    ;

    proclist:
        proclist _SEMI procdef      {printf("Rule in proclist: proclist _SEMI procdef \n");}
        | procdef       {printf("Rule in proclist: procdef \n");}
    ;

    procdef:
        ptitle _SEMI block  {printf("Rule in procdef: ptitle _SEMI block \n");}
    ;

    ptitle:
        _PROC _ID _LPAREN varlist _RPAREN   {printf("Rule in ptitle: _PROC _ID _LPAREN varlist _RPAREN \n");}
        | _PROC _ID _LPAREN _RPAREN         {printf("Rule in ptitle: _PROC _ID _LPAREN _RPAREN \n");}
    ;

    code:
        _BEGIN para _END {printf("Rule in code: _BEGIN para _END \n");}
        | _SEMI         {printf("Rule in code:  _SEMI \n");}
    ;

    para:
        para _SEMI stmt     {printf("Rule in para: para _SEMI stmt \n");}
        | stmt              {printf("Rule in para: stmt \n");}
    ;

    stmt:
        assign      {printf("Rule in stmt: assign \n");}
        | cond      {printf("Rule in stmt: cond \n");}
        | loop      {printf("Rule in stmt: loop \n");}
        | input     {printf("Rule in stmt: input \n");}
        | output    {printf("Rule in stmt: output \n");}
        | code      {printf("Rule in stmt: code \n");}
    ;

    assign:
         ids _ASSIGN expr   {printf("Rule in assign: ids _ASSIGN expr \n");}
    ;

    expr:
        expr _PLUS term     {printf("Rule in expr: expr _PLUS term \n");}
        | expr _MINUS term  {printf("Rule in expr: expr _MINUS term \n");}
        | term  {printf("Rule in expr: term \n");}
    ;

    ids:
        _ID {printf("Rule in ids: _ID \n");}
        | _ID _LBRACK vallist _RBRACK   {printf("Rule in ids: _ID _LBRACK vallist _RBRACK \n");}
    ;

    term:
        term _MULT fac      {printf("Rule in term: term _MULT fac  \n");}
        | term _DIVIDE fac  {printf("Rule in term: term _DIVIDE fac \n");}
        | fac   {printf("Rule in term: fac \n");}
    ;

    vallist:
        vallist _COMMA it   {printf("Rule in vallist: vallist _COMMA it  \n");}
        | it    {printf("Rule in vallist: it \n");}
    ;

    fac:
        val     {printf("Rule in fac: val \n");}
        | _LPAREN expr _RPAREN      {printf("Rule in fac: _LPAREN expr _RPAREN \n");}
    ;

    val:
        ids     {printf("Rule in val: ids \n");}
        | _ID _LPAREN vallist _RPAREN   {printf("Rule in val: _ID _LPAREN vallist _RPAREN\n");}
        | _ICONST   {printf("Rule in val: _ICONST \n");}    
        | _RCONST   {printf("Rule in val: _RCONST \n");}
        | _ECONST   {printf("Rule in val: _ECONST \n");}
        | _LITERAL  {printf("Rule in val: _LITERAL \n");}
    ;


    it:
        _ID {printf("Rule in it: _ID \n");}
        | _ICONST   {printf("Rule in it: _ICONST \n");}
    ;

    cond: 
        _IF expr bop expr _THEN stmt _ELSE stmt     {printf("Rule in cond: _IF expr bop expr _THEN stmt _ELSE stmt \n");}
    ;

    bop:
        _EQL {printf("Rule in bop: _EQL \n");}
        | _LESS {printf("Rule in bop: _LESS \n");}
        | _GTR  {printf("Rule in bop: _GTR \n");}
        | _LEQ  {printf("Rule in bop: _LEQ \n");}
        | _GEQ  {printf("Rule in bop: _GEQ \n");}
        | _NEQ  {printf("Rule in bop: _NEQ \n");}
    ;
        
    loop:   
        _FOR assign _TO expr _DO stmt   {printf("Rule in loop: _FOR assign _TO expr _DO stmt \n");}
    ;
    
    input:
        _READ _LPAREN _ID _RPAREN   {printf("Rule in input: _READ _LPAREN _ID _RPAREN \n");}
    ;

    output:
        _WRITE _LPAREN _ID _RPAREN      {printf("Rule in output: _WRITE _LPAREN _ID _RPAREN \n");}
        | _WRITE _LPAREN _LITERAL _RPAREN   {printf("Rule in output: _WRITE _LPAREN _LITERAL _RPAREN \n");}
    ;


%%


int yyerror(char *s)
{
    printf ("yyerror :%s\n", s);
    return (0);
}

And this it my scanner.l

%option noyywrap

D [0-9]
A [a-zA-Z]

%{
#include "Tokens.h"

#include "lex.yy.x"

int tokenCount;
%}

%%
"["                         {tokenCount++; return (_LBRACK);}
"]"                         {tokenCount++; return (_RBRACK);}
"("                         {tokenCount++; return (_LPAREN);}
")"                         {tokenCount++; return (_RPAREN);}
";"                         {tokenCount++; return (_SEMI);}
":"                         {tokenCount++; return (_COLON);}
","                         {tokenCount++; return (_COMMA);}
":="                            {tokenCount++; return (_ASSIGN);}
"+"                         {tokenCount++; return (_PLUS);}
"-"                         {tokenCount++; return (_MINUS);}
"*"                         {tokenCount++; return (_MULT);}
"/"                         {tokenCount++; return (_DIVIDE);}
"="                         {tokenCount++; return (_EQL);}
"<"                         {tokenCount++; return (_LESS);}
">"                         {tokenCount++; return (_GTR);}
"<="                            {tokenCount++; return (_LEQ);}
">="                            {tokenCount++; return (_GEQ);}
"<>"                            {tokenCount++; return (_NEQ);}
[Pp][Rr][Oo][Gg][Rr][Aa][Mm]                {tokenCount++; return (_PROGRAM);}
[Ee][Nn][Dd][Vv][Aa][Rr][Ss]                {tokenCount++; return (_ENDVARS);}
[Ee][Nn][Dd][Pp][Rr][Oo][Cs][Ss]            {tokenCount++; return (_ENDPROCS);}
[Vv][Aa][Rr][Ii][Aa][Bb][Ll][Ee][Ss]            {tokenCount++; return (_VARS);}
[Nn][Oo][Vv][Aa][Rr][Ii][Aa][Bb][Ll][Ee][Ss]        {tokenCount++; return (_NOVARS);}
[Ii][Nn][Tt][Ee][Gg][Ee][Rr]                {tokenCount++; return (_INTEGER);}
[Rr][Ee][Aa][Ll]                    {tokenCount++; return (_REAL);}
[Ss][Tt][Rr][Ii][Nn][Gg]                {tokenCount++; return (_STRING);}
[Pp][Rr][Oo][Cc][Ee][Dd][Uu][Rr][Ee][Ss]        {tokenCount++; return (_PROCS);}
[Nn][Oo][Pp][Rr][Oo][Cc][Ee][Dd][Uu][Rr][Ee][Ss]    {tokenCount++; return (_NOPROCS);}
[Pp][Rr][Oo][Cc][Ee][Dd][Uu][Rr][Ee]            {tokenCount++; return (_PROC);}
[Bb][Ee][Gg][Ii][Nn]                    {tokenCount++; return (_BEGIN);}
[Ee][Nn][Dd]                        {tokenCount++; return (_END);}
[Ff][Oo][Rr]                        {tokenCount++; return (_FOR);}
[Tt][Oo]                        {tokenCount++; return (_TO);}
[Dd][Oo]                        {tokenCount++; return (_DO);}
[Ii][Ff]                        {tokenCount++; return (_IF);}
[Tt][Hh][Ee][Nn]                    {tokenCount++; return (_THEN);}
[Ee][Ll][Ss][Ee]                    {tokenCount++; return (_ELSE);}
[Rr][Ee][Aa][Dd]                    {tokenCount++; return (_READ);}
[Ww][Rr][Ii][Tt][Ee]                    {tokenCount++; return (_WRITE);}
[a-zA-Z0-9\-?\_?]+                  {tokenCount++; return (_ID);}
([+-]?[0-9]*\.[0-9]+[eE][\+-]?[0-9]+)|([+-]?[0-9]+[eE][\+-]?[0-9]+) {tokenCount++; return (_ECONST);}
[\+-]?[0-9]+                        {tokenCount++; return (_ICONST);}
[\+-]?[0-9]*.[0-9]+                 {tokenCount++; return (_RCONST);}
\{'.*'\}|\{".*"\}                   {tokenCount++; return (_LITERAL);}
\{.*\}                          {tokenCount++; return (_COMEN);}
\{[a-zA-Z0-9~!@#$%^&*()_+|":?><.,';\-\/*\ ]+        {tokenCount++; return (_ERROR1);}
\"[a-zA-Z0-9~!@#$%^&*()_+|:?><.,';\-\/*{}\ ]+       {tokenCount++; return (_ERROR2);}
.

%%

void yyerror(int tokenCount)
{
    printf("Hubo un error al analizar el lexema %s en la columna %d", yytext, tokenCount);
    exit(1);
}

void yytrap() {}

This is my output:

Rule in title: _PROGRAM _ID 
Rule in vardef: _ID _COLON _REAL 
Rule in varlist: vardefRule in vardef: _ID _COLON _INTEGER 
Rule in varlist: varlist _SEMI vardef 
Rule in vardef: _ID _COLON _STRING 
Rule in varlist: varlist _SEMI vardef 
Rule in nlist: _ICONST 
Rule in bnl: _LBRACK nlist _RBRACK 
Rule in vardef: _ID _COLON _INTEGER bnl 
Rule in varlist: varlist _SEMI vardef 
Rule in nlist: _ICONST 
Rule in nlist: nlist _COMMA _ICONST 
Rule in bnl: _LBRACK nlist _RBRACK 
Rule in vardef: _ID _COLON _INTEGER bnl 
Rule in varlist: varlist _SEMI vardef 
Rule in vars: _VARS varlist _SEMI 
Rule in ptitle: _PROC _ID _LPAREN _RPAREN 
Rule in vars: _NOVARSRule in procs: _NOPROCS 
Rule in code:  _SEMI 
Rule in stmt: code 
Rule in para: stmt 
Rule in code: _BEGIN para _END 
Rule in block: _PROGRAM _ID 
Rule in procdef: ptitle _SEMI block 
Rule in proclist: procdef 
Rule in vardef: _ID _COLON _INTEGER 
Rule in varlist: vardefRule in ptitle: _PROC _ID _LPAREN varlist _RPAREN 
Rule in vardef: _ID _COLON _INTEGER 
Rule in varlist: vardefRule in vardef: _ID _COLON _STRING 
Rule in varlist: varlist _SEMI vardef 
Rule in vars: _VARS varlist _SEMI 
Rule in procs: _NOPROCS 
Rule in ids: _ID 
Rule in val: _ICONST 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in assign: ids _ASSIGN expr 
Rule in ids: _ID 
Rule in val: ids 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in output: _WRITE _LPAREN _LITERAL _RPAREN 
Rule in stmt: output 
Rule in loop: _FOR assign _TO expr _DO stmt 
Rule in stmt: loop 
Rule in para: stmt 
Rule in output: _WRITE _LPAREN _LITERAL _RPAREN 
Rule in stmt: output 
Rule in para: para _SEMI stmt 
Rule in code: _BEGIN para _END 
Rule in block: _PROGRAM _ID 
Rule in procdef: ptitle _SEMI block 
Rule in proclist: proclist _SEMI procdef 
Rule in vardef: _ID _COLON _REAL 
Rule in varlist: vardefRule in ptitle: _PROC _ID _LPAREN varlist _RPAREN 
Rule in vardef: _ID _COLON _REAL 
Rule in varlist: vardefRule in vars: _VARS varlist _SEMI 
Rule in procs: _NOPROCS 
Rule in ids: _ID 
Rule in ids: _ID 
Rule in val: ids 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in assign: ids _ASSIGN expr 
Rule in stmt: assign 
Rule in para: stmt 
Rule in it: _ID 
Rule in vallist: it 
Rule in ids: _ID _LBRACK vallist _RBRACK 
Rule in val: _ICONST 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in assign: ids _ASSIGN expr 
Rule in stmt: assign 
Rule in para: para _SEMI stmt 
Rule in ids: _ID 
Rule in ids: _ID 
Rule in val: ids 
Rule in fac: val 
Rule in term: fac 
Rule in ids: _ID 
Rule in val: ids 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in ids: _ID 
Rule in val: ids 
Rule in fac: val 
Rule in term: fac 
Rule in expr: expr _PLUS term 
Rule in fac: _LPAREN expr _RPAREN 
Rule in term: term _DIVIDE fac 
Rule in val: _ICONST 
Rule in fac: val 
Rule in term: term _MULT fac  
Rule in expr: term 
Rule in assign: ids _ASSIGN expr 
Rule in stmt: assign 
Rule in para: para _SEMI stmt 
Rule in ids: _ID 
Rule in it: _ID 
Rule in vallist: it 
Rule in it: _ID 
Rule in vallist: vallist _COMMA it  
Rule in ids: _ID _LBRACK vallist _RBRACK 
Rule in val: ids 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in assign: ids _ASSIGN expr 
Rule in stmt: assign 
Rule in para: para _SEMI stmt 
Rule in code: _BEGIN para _END 
Rule in block: _PROGRAM _ID 
Rule in procdef: ptitle _SEMI block 
Rule in proclist: proclist _SEMI procdef 
Rule in vardef: _ID _COLON _STRING 
Rule in varlist: vardefRule in ptitle: _PROC _ID _LPAREN varlist _RPAREN 
Rule in vardef: _ID _COLON _INTEGER 
Rule in varlist: vardefRule in vars: _VARS varlist _SEMI 
Rule in procs: _NOPROCS 
Rule in ids: _ID 
Rule in val: ids 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in bop: _EQL 
Rule in ids: _ID 
Rule in val: ids 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in output: _WRITE _LPAREN _LITERAL _RPAREN 
Rule in stmt: output 
Rule in input: _READ _LPAREN _ID _RPAREN 
Rule in stmt: input 
Rule in cond: _IF expr bop expr _THEN stmt _ELSE stmt 
Rule in stmt: cond 
Rule in para: stmt 
Rule in ids: _ID 
Rule in val: ids 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in bop: _EQL 
Rule in val: _ICONST 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in output: _WRITE _LPAREN _LITERAL _RPAREN 
Rule in stmt: output 
Rule in ids: _ID 
Rule in val: ids 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in bop: _GTR 
Rule in val: _ICONST 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in input: _READ _LPAREN _ID _RPAREN 
Rule in stmt: input 
Rule in input: _READ _LPAREN _ID _RPAREN 
Rule in stmt: input 
Rule in cond: _IF expr bop expr _THEN stmt _ELSE stmt 
Rule in stmt: cond 
Rule in cond: _IF expr bop expr _THEN stmt _ELSE stmt 
Rule in stmt: cond 
Rule in para: para _SEMI stmt 
Rule in ids: _ID 
Rule in val: ids 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in bop: _NEQ 
Rule in val: _ICONST 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in output: _WRITE _LPAREN _LITERAL _RPAREN 
Rule in stmt: output 
Rule in output: _WRITE _LPAREN _ID _RPAREN 
Rule in stmt: output 
Rule in cond: _IF expr bop expr _THEN stmt _ELSE stmt 
Rule in stmt: cond 
Rule in para: para _SEMI stmt 
Rule in ids: _ID 
Rule in val: ids 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in bop: _EQL 
Rule in val: _ICONST 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in ids: _ID 
Rule in val: _RCONST 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in assign: ids _ASSIGN expr 
Rule in stmt: assign 
Rule in ids: _ID 
Rule in val: _RCONST 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in assign: ids _ASSIGN expr 
Rule in stmt: assign 
Rule in cond: _IF expr bop expr _THEN stmt _ELSE stmt 
Rule in stmt: cond 
Rule in para: para _SEMI stmt 
Rule in ids: _ID 
Rule in val: _ICONST 
Rule in fac: val 
Rule in term: fac 
Rule in it: _ICONST 
Rule in vallist: it 
Rule in it: _ICONST 
Rule in vallist: vallist _COMMA it  
Rule in val: _ID _LPAREN vallist _RPAREN
Rule in fac: val 
Rule in term: term _MULT fac  
Rule in expr: term 
Rule in assign: ids _ASSIGN expr 
Rule in stmt: assign 
Rule in para: para _SEMI stmt 
Rule in code: _BEGIN para _END 
Rule in block: _PROGRAM _ID 
Rule in procdef: ptitle _SEMI block 
Rule in proclist: proclist _SEMI procdef 
Rule in procs: _PROCS proclist 
 Rule in code:  _SEMI 
Rule in block: _PROGRAM _ID 
Rule in program: _SEMI 
yyerror :syntax error
yyerror :syntax error
cucucu
  • 1
  • 3
  • Impossible to say with only this information. You need to print the line number at which the error occurred, and preferably also the current token. – user207421 Mar 25 '21 at 02:38
  • Why do you insist on numbering your own tokens rather than letting bison do it for you? If you are going to do it, you really should use names which are not reserved, since token names are used as identifiers in the generated code. In C and C++, all identifiers starting with an underscore followed by an upper-case letter or another underscore are reserved, so you shouldn't be using them. – rici Mar 25 '21 at 02:55
  • In addition to what @user207421 said, you should really consider using bison's built-in trace facility rather than trying to generate your own debugging output. Bison's traces are a lot more informative (and a lot less work for you, too). See the ["Debugging your parser" section in the bison manual.](https://www.gnu.org/software/bison/manual/bison.html#Tracing) – rici Mar 25 '21 at 02:57
  • Oh, and flex has a [handy option](http://westes.github.io/flex/manual/Options-Affecting-Scanner-Behavior.html#index-_002d_002d_002dcase_002dinsensitive) for making patterns case-insensitive. – rici Mar 25 '21 at 03:00
  • Okey, thanks I going to check – cucucu Mar 25 '21 at 03:04
  • Another thing: you don't show the code which calls yyparse. You also don't show how you're building the executable, or where the header files you `#include` cone from. – rici Mar 25 '21 at 07:35

0 Answers0