我正在使用CUP和JFLEX进行pascal编译器。要求之一是从错误中恢复并显示错误在哪里。
我一直在使用syntax_error
和unrecovered_syntax_error
的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));
}
:}
这是我的CFG的一部分,我只关注声明错误产生的地方
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;
这是我的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();
}
}
}
我相信s.right和s.left会在出现新错误时更改其值,但是当我遇到两个错误时:
program ejemplo;
begin
a 1;
b := 2;
while x+2
a:= 1;
end.
它应该返回
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]
其中numberX和numberY可以彼此相等,而numberW和numberZ可以彼此相等,但是一对不能等于另一对。
但是,它返回了我
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
如果有人帮助我了解这种情况的发生原因和/或解决方法,我将不胜感激。
答案 0 :(得分:0)
我不能真正回答您的问题:为什么Symbol的字段(左右)总是返回0?因为您没有向我们显示您的扫描仪规范代码;符号在扫描仪中初始化。
但是,如果要使每个符号的左和右值分别等于其行和列,则必须从扫描仪设置该信息。解析器不会在源代码中跟踪符号的位置。
我假设您正在将jflex用于扫描仪生成器;这是一个示例,说明如何使用%line
和%column
选项使用行和列返回Symbols:
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>