0

I'm working on a pascal compiler using CUP and JFLEX. One of the requirements is to recover from errors and show where the errors are.

I've been using CUP's method of syntax_error and unrecovered_syntax_error

This is the parser code in my parser.cup

parser code
{:
        public static Nodo padre;
        public int cont = 0;

        public void syntax_error(Symbol s) {
            System.out.println("Error sintáctico. No se esperaba el siguiente token: <" + s.value + ">. Línea: " + (s.left + 1) + ", Columna: " + (s.right + 1));
        }

        public void unrecovered_syntax_error(Symbol s) throws java.lang.Exception {
            System.out.println("Error sintáctico cerca del token: <" + s.value + ">. Línea: " + (s.left + 1) + ", Columna: " + (s.right + 1));
        } 
:}

This is part of my CFG, which I'm only focusing where I'm declaring the error production

programa ::=
            inicioPrograma:inicProg declaraciones_const:declConst declaraciones_tipo:declTipo declaraciones_var:declVar declaraciones_subprogramas:declSubp proposicion_compuesta:propComp DOT
            ;

proposicion_compuesta ::=
                        BEGIN proposiciones_optativas END;

proposiciones_optativas ::=
                            lista_proposiciones
                            | /* lambda */;

lista_proposiciones ::=
                        proposicion SEMICOLON
                        | proposicion SEMICOLON lista_proposiciones;

proposicion ::=
                variable ASSIGNMENT expresion
                {:
                    System.out.println("hola");
                :}
                | proposicion_procedimiento
                | proposicion_compuesta
                | IF expresion THEN proposicion
                | IF expresion THEN proposicion ELSE proposicion
                | WHILE expresion DO proposicion
                | FOR ID ASSIGNMENT expresion TO expresion DO proposicion
                | FOR ID ASSIGNMENT expresion DOWNTO expresion DO proposicion
                | REPEAT proposicion UNTIL expresion
                | READ LPAR ID RPAR
                | WRITE LPAR CONST_STR RPAR
                | WRITE LPAR CONST_STR COMMA ID RPAR
                | error;

And this is my Main.java

import java.io.*;

public class Main {
  static public void main(String argv[]) {    
    /* Start the parser */
    try {
      parser p = new parser(new LexicalElements(new FileReader(argv[0])));
     p.parse(); 
    } catch (Exception e) {
      e.printStackTrace();
    }

  }
}

I believe that s.right and s.left should change its value when a new error comes in, but when I've two errors like:

program ejemplo;

begin
    a  1;
    b := 2;
    while x+2 
        a:= 1;
end.

It should return

Error sintáctico. No se esperaba el siguiente token: <1>. Línea: [numberX], Columna: [numberY]
Error sintáctico. No se esperaba el siguiente token: <a>. Línea: [numberW], Columna: [numberZ]

Where numberX and numberY may equal to each other, numberW and numberZ may equal to each, but a pair can't equal to another pair.

Yet, it returns me

Error sintáctico. No se esperaba el siguiente token: <1>. Línea: 1, Columna: 1
Error sintáctico. No se esperaba el siguiente token: <a>. Línea: 1, Columna: 1

I would gladly appreciate if someone helps me to understand as to why this is occurring and/or how to solve it.

1 Answers1

0

I can't really answer your question: Why do Symbol's fields (left and right) always return 0? Since you didn't show us your scanner specification code; Symbols are initialized in the scanner.

However, if what you want is to have the left and right value of each symbol equal to its line and column respectively you have to set that information from the scanner. The parser doesn't keep track of the symbol's location in the source code.

I assume you are using jflex for your scanner generator, if so; here is an example of how you can return Symbols with line and column using the %line and %column options:

import java_cup.runtime.*;
%%
%cup

//switches line counting on (the current line is accessed via yyline) 
%line
//switches column counting on (the current column is accessed via yycolumn)
%column
IntegerRegex= [0-9]+
%%
<YYINITIAL> 
    "keyword" { 
        return new Symbol(sym.KEYWORD, yyline, yycolumn); 
    }

    {IntegerRegex} { 
        return new Symbol(sym.INTEGER_LITERAL, yyline, yycolumn, Integer.valueOf(yytext())); 
    }
</YYINITIAL>
Javier
  • 55
  • 9