1

I'm trying to implement a very simple parser, but I'm having a problem. I have the following grammar:

%lex

%options flex case-insensitive

CaracterEscape              [\'\"\\bfnrtv]
Escape                      \\{CaracterEscape}
CaracterCadena              [^\"\\]+
CadenaDoble                 ({Escape}|{CaracterCadena})
LiteralCadena               \"{CadenaDoble}*\"
CaracterChar                [^\'\\]
CadenaSimple                {Escape}|{CaracterChar}
LiteralChar                 \'{CadenaSimple}\'

%%

\s+                                     {}                               
"//".*                                  {}
[/][*][^*]*[*]+([^/*][^*]*[*]+)*[/]     {}

"+"                         return 'A_MAS';
"-"                         return 'A_MENOS';
"*"                         return 'A_MULTI';
"/"                         return 'A_DIV';
"**"                        return 'A_POTENCIA';
"%"                         return 'A_MOD';

"++"                        return 'O_INCREMENTO';
"--"                        return 'O_DECREMENTO';

"="                         return 'O_ASIGNACION';

"<"                         return 'R_MENOR_QUE';
">"                         return 'R_MAYOR_QUE';
"<="                        return 'R_MENOR_IGUAL';
">="                        return 'R_MAYOR_IGUAL';
"=="                        return 'R_IGUAL';
"!="                        return 'R_DIFERENTE';

"||"                        return 'L_OR';
"&&"                        return 'L_AND';
"^"                         return 'L_XOR';
"!"                         return 'L_NOT';

","                         return 'S_COMA';
";"                         return 'S_PUNTO_COMA';
":"                         return 'S_DOS_PUNTOS';
"("                         return 'S_PAR_APERTURA';
")"                         return 'S_PAR_CIERRE';
"{"                         return 'S_LLAVE_APERTURA';
"}"                         return 'S_LLAVE_CIERRE';

"int"                       return 'T_INT';
"double"                    return 'T_DOUBLE';
"char"                      return 'T_CHAR';
"boolean"                   return 'T_BOOLEAN';
"string"                    return 'T_STRING';

"if"                        return 'I_IF';
"else"                      return 'I_ELSE';
"switch"                    return 'I_SWITCH';
"case"                      return 'I_CASE';
"default"                   return 'I_DEFAULT';
"break"                     return 'I_BREAK';
"for"                       return 'I_FOR';
"while"                     return 'I_WHILE';
"do"                        return 'I_DO_WHILE';
"continue"                  return 'I_CONTINUE';

"void"                      return 'P_VOID';
"const"                     return 'P_CONSTANTE';

"call"                      return 'F_CALL';
"return"                    return 'F_RETURN';
"print"                     return 'F_PRINT';
"println"                   return 'F_PRINTLN';
"typeof"                    return 'F_TYPEOF';

[0-9]+\b                    return 'ENTERO';
[0-9]+("."[0-9]+)?\b        return 'DECIMAL';
{LiteralChar}               return 'CARACTER';
{LiteralCadena}             return 'CADENA';
                            
("true"|"false")            return 'BOOLEANO';

[a-zA-Z_][a-zA-Z0-9_]*      return 'ID';

<<EOF>>                     return 'EOF';

.                           {
                                console.error(`Error lexico: ${yytext}, en:\nlinea: ${yylloc.first_line}, columna: ${yylloc.first_column + 1}`);
                            }

/lex

%{
%}

%left           'L_OR'
%left           'L_AND'
%left           'L_XOR'
%nonassoc       'R_MENOR_QUE' 'R_MAYOR_QUE' 'R_MENOR_IGUAL' 'R_MAYOR_IGUAL' 'R_IGUAL' 'R_DIFERENTE'
%left           'R_IGUAL' 'R_DIFERENTE'
%left           'R_MAYOR_QUE' 'R_MENOR_QUE' 'R_MAYOR_IGUAL' 'R_MENOR_IGUAL'
%left           'A_MAS' 'A_MENOS'
%left           'A_MULTI' 'A_DIV' 'A_MOD'
%right          'A_POTENCIA'
%right          'UMINUS' 'L_NOT'
%right          'O_INCREMENTO' 'O_DECREMENTO'
//%right          'S_PAR_APERTURA'

%start axioma

%%

axioma          :           S_LLAVE_APERTURA instrucciones S_LLAVE_CIERRE  EOF {                                
                            };

instrucciones   :           instrucciones instruccion {
                     
                                }
                            }
                |           instruccion {
                         
                            };

instruccion     :           asignacion fin_instr {
                     
                            }                
                |           call func {
}
                            }
                |           error {
                                console.log(`Error sintactico en: linea ${@1.first_line}, columna ${@1.first_column} `);
                            };


expresion       :           expresion A_MAS expresion {                                
                     
                            }
                |           expresion A_MENOS expresion {
                     
                            }
                |           expresion A_MULTI expresion {
                     
                            }
                |           expresion A_DIV expresion {
                     
                            }
                |           expresion A_POTENCIA expresion {
                     
                            }
                |           expresion A_MOD expresion {
                     
                            }
                |           A_MENOS expresion %prec UMINUS {
                     
                            }
                |           expresion R_MENOR_QUE expresion {
                     
                            }
                |           expresion R_MAYOR_QUE expresion {
                     
                            }
                |           expresion R_MENOR_IGUAL expresion {
                     
                            }
                |           expresion R_MAYOR_IGUAL expresion {
                     
                            }
                |           expresion R_IGUAL expresion {
                     
                            }
                |           expresion R_DIFERENTE expresion {
                     
                            }
                |           expresion L_AND expresion {
                     
                            }
                |           expresion L_OR expresion {
                     
                            }
                |           expresion L_XOR expresion {
                     
                            }
                |           L_NOT expresion {                                
                     
                            }
                |           S_PAR_APERTURA expresion S_PAR_CIERRE {
                     
                            }
                |           ENTERO {
                     
                            }
                |           DECIMAL {
                     
                            }
                |           CARACTER {
                     
                            }
                |           CADENA {
                     
                            }
                |           BOOLEANO {                                
                     
                            }
                |           ID {
                     
                            };

asignacion      :           ID O_ASIGNACION expresion {
                     
                            }
                |           ID O_INCREMENTO {                                
                     
                            }
                |           ID O_DECREMENTO {                                
                     
                            };

lista_params    :           lista_params COMA expresion {
                     
                            }
                |           expresion {
                     
                            };

call_func       :           F_CALL ID S_PAR_APERTURA S_PAR_CIERRE {
                            }
                |           F_CALL ID S_PAR_APERTURA lista_params S_PAR_CIERRE {
};

fin_instr       :           S_PUNTO_COMA;

The grammar contains more productions but it is this part that is creating conflicts. The problem comes when trying to parse the following text:

{
    call add(2, 3)
}

JISON tells me that there was a syntactic error in '(', however the characters are provided by the lexical analyzer, so I think the problem may be the grammar but I really don't understand what the cause is. Any ideas?

The output is: Error sintactico en: linea 2, columna 18

luis-epa
  • 21
  • 2
  • 1
    " I think the problem may be the grammar but I really don't understand what the cause is." In that case, why are you so confident that the problem is in the extract if the grammar you show? Grammar questions should always be illustrated with a complete grammar, a [mre]. If you think only a part of the grammas is relevant, create a smaller complete program with fewer productions and see if it has the same problem. If not,. add productions back until the problems return. (That's also a good debugging technique.) – rici Jun 18 '22 at 12:22
  • @rici I have created the minimum reproducible example, and the problem persists. The parser is not able to recognize the input, I don't know why? – luis-epa Jun 18 '22 at 16:16
  • Where is `call_func` being used in your grammar? – robertklep Jun 18 '22 at 16:36
  • @robertklep I made the mistake writing it here, I already added the missing output. I don't understand what is wrong? – luis-epa Jun 18 '22 at 17:00
  • 1
    It worked fine for me after I removed the extra `}` in the production for `instrucciones`, changed `call func` to `call_func` in the production for `instruccion`, and changed `COMA` to `S_COMA` in the production for `lista_params`. So I think this was all just a typo. – rici Jun 18 '22 at 22:16
  • Thank you very much, it was precisely the comma the comma token that was causing problems. You saved my life. – luis-epa Jun 18 '22 at 22:29
  • 1
    This is why I always recommend using character literals (like `','`) instead of thinking up complicated names for simple tokens. Unnecessary naming is a frequent cause of errors (not just in jison). Also, the error message said that the syntax error was detected at column 18, which is the `)`. Perhaps in your original there were more spaces at the beginning of the line, since the error is the `,`, which is column 15. – rici Jun 18 '22 at 22:32

0 Answers0