Parsing Javacc解析器生成器无法识别我的语言(输入)

Parsing Javacc解析器生成器无法识别我的语言(输入),parsing,pascal,javacc,parser-generator,Parsing,Pascal,Javacc,Parser Generator,我正在使用Javacc为Pascal子集构建一个解析器 这是我的代码: PARSER_BEGIN(Pascal) import java.io.*; public class Pascal { public static void main(String args[]) throws ParseException,IOException { Pascal parser = new Pascal(new FileInputStream(args[0])); parser.P

我正在使用Javacc为Pascal子集构建一个解析器

这是我的代码:

PARSER_BEGIN(Pascal)
import java.io.*;
public class Pascal {

  public static void main(String args[]) throws ParseException,IOException {

    Pascal parser = new Pascal(new FileInputStream(args[0]));
    parser.Programa();
  }

}

PARSER_END(Pascal)

SKIP :
{
  " "
| "\t"
| "\n"
| "\r"
}

TOKEN :
{
  <PROGRAM: "program">
| <INTEIRO: "integer">
| <REAL: "real">
| <VAR: "var">
| <OF: "of">
| <FUNCTION: "function">
| <PROCEDURE: "procedure">
| <LBRACE:"(">
| <RBRACE: ")">
| <SEMI: ";">
| <PTS: ":">
| <BEGIN: "begin">
| <END: "end">
| <ATRIB: ":=">
| <ARRAY: "array">
| <LBRACKETS: "[">
| <RBRACKETS: "]">
| <IF: "if">
| <THEN: "then">
| <ELSE: "else">
| <NOT: "not">
| <PLUS: "+">
| <MINUS: "-">
| <WHILE: "while">
| <DO: "do">
}

TOKEN :
{
 <OPERADOR_MULTIPLICATIVO: ("*"|"/"|"div"|"mod"|"and")>
|
 <OPERADOR_ADITIVO: ("+"| "-" | "or")>
|
 <OPERADOR_RELACIONAL: ("=" | "<>" | "<" | "<=" | ">=" | ">")>
|
 <ID: ["a"-"z","A"-"Z"] ( ["a"-"z","A"-"Z","0"-"9"])*>
|
 <DIGT: ["0"-"9"] (["0"-"9"])*>

}



void Programa () :
{}
{ <PROGRAM> <ID> <LBRACE> Lista_de_identificadores() <RBRACE> <SEMI> 
  Declaracoes()
  Declara_subprogram() 
  Enunciado_composto()
  <EOF> 
}

// lista_de_identificadores

void Lista_de_identificadores():
{}
{
  <ID> Lista2()
}

void Lista2():
{}
{
 ("," <ID> Lista2())?
}

//declarações

void Declaracoes():
{}
{
    (<VAR> Lista_de_identificadores() <PTS> Tipo() <SEMI>)*
}

// tipo

void Tipo():
{}
{
    (Tipo_padrao() | <ARRAY> <LBRACKETS> <DIGT> <RBRACKETS> <OF> Tipo_padrao())
}

//tipo_padrao

void Tipo_padrao():
{}
{
    (<INTEIRO> | <REAL>)
}

//declarações_de_subprogramas

void Declara_subprogram():
{}
{
    (Subprogram() <SEMI>)*
}

//declaração_de_subprograma

void Subprogram():
{}
{
    Cabecalho_subprogram()
    Declaracoes()
    Enunciado_composto()
}

//cabeçalho_de_subprograma

void Cabecalho_subprogram():
{}
{
    (<FUNCTION> <ID> Argumentos() <PTS> Tipo_padrao() <SEMI>) | (<PROCEDURE> <ID> Argumentos())
}

//argumentos

void Argumentos():
{}
{
    (<LBRACE> Lista_parametros() <RBRACE>)?
}

//lista_de_parâmetros

void Lista_parametros():
{}
{
    Lista_de_identificadores() <PTS> Tipo() Lista_parametros2()
}

void Lista_parametros2():
{}
{
    (<SEMI> Lista_de_identificadores() <PTS> Tipo() Lista_parametros2())?
}

//enunciado_composto

void Enunciado_composto():
{}
{
    <BEGIN> Enunciados_opcionais() <END>    
}

//enunciados_opcionais

void Enunciados_opcionais():
{}
{
    (Lista_enunciados())?
}

//lista_de_enunciados

void Lista_enunciados():
{}
{
    Enunciado() (<SEMI> Enunciado())*
}

void Enunciado():
{}
{
    LOOKAHEAD(5)(Variavel() <ATRIB> Expressao()) | (Chamada_procedimento()) | (Enunciado_composto()) | (<IF> Expressao() <THEN> Enunciado() <ELSE> Enunciado()) | (<WHILE> Expressao() <DO> Enunciado())
}

void Variavel():
{}
{
    LOOKAHEAD(2)(<ID>) | (<ID> <LBRACKETS> Expressao() <RBRACKETS>)
}

void Chamada_procedimento():
{}
{
    LOOKAHEAD(2)(<ID>) | (<ID> <LBRACE> Lista_expressoes() <RBRACE>)
}

void Lista_expressoes():
{}
{
    Expressao() Lista_expressoes2() 
}

void Lista_expressoes2():
{}
{
    ("," Expressao() Lista_expressoes2())?
}

void Expressao():
{}
{
    LOOKAHEAD(2)Expressao_simples() | Expressao_simples() <OPERADOR_RELACIONAL> Expressao_simples()
}

void Expressao_simples():
{}
{
    LOOKAHEAD(3)(Termo() Expressao_simples2()) | (Sinal() Termo() Expressao_simples2())
}

void Expressao_simples2():
{}
{
    (<OPERADOR_ADITIVO> Termo() Expressao_simples2())?
}

void Termo():
{}
{
    Fator() Termo2()
}

void Termo2():
{}
{
    (<OPERADOR_MULTIPLICATIVO> Fator() Termo2())?
}

void Fator():
{}
{
    LOOKAHEAD(2)(<ID>) | (<ID> <LBRACE> Lista_expressoes() <RBRACE>) | (<DIGT>) | (<LBRACE> Expressao() <RBRACE>) | (<NOT> Fator())
}

void Sinal():
{}
{
    (<PLUS> | <MINUS>)
}
Javacc返回以下内容:

Exception in thread "main" ParseException: Encountered " <OPERADOR_RELACIONAL> "= "" at line 5, column 14.
Was expecting one of:
    "then" ...
    <OPERADOR_MULTIPLICATIVO> ...
    <OPERADOR_ADITIVO> ...
    <OPERADOR_MULTIPLICATIVO> ...
    <OPERADOR_ADITIVO> ...
    <OPERADOR_ADITIVO> ...
    <OPERADOR_MULTIPLICATIVO> ...
    <OPERADOR_ADITIVO> ...

        at Pascal.generateParseException(Pascal.java:984)
        at Pascal.jj_consume_token(Pascal.java:865)
        at Pascal.Enunciado(Pascal.java:270)
        at Pascal.Lista_enunciados(Pascal.java:235)
        at Pascal.Enunciados_opcionais(Pascal.java:223)
        at Pascal.Enunciado_composto(Pascal.java:211)
        at Pascal.Subprogram(Pascal.java:137)
        at Pascal.Declara_subprogram(Pascal.java:127)
        at Pascal.Programa(Pascal.java:20)
        at Pascal.main(Pascal.java:9)
线程“main”ParseException中的异常:在第5行第14列遇到“=”。 我期待的是: “那么……”。。。 ... ... ... ... ... ... ... 在Pascal.generateParseException处(Pascal.java:984) 在Pascal.jj_消费_令牌(Pascal.java:865) 在Pascal.Enunciado(Pascal.java:270) 在Pascal.Lista_enuciados(Pascal.java:235) 在Pascal.Enuniciados_opcionais(Pascal.java:223) 在Pascal.Enunciado_composto(Pascal.java:211) 子程序(Pascal.java:137) 在Pascal.Declara_子程序中(Pascal.java:127) 在Pascal.Programa(Pascal.java:20) 位于Pascal.main(Pascal.java:9) 问题是,我不明白为什么Javacc期望这些参数,并在他所在的位置g处调用“=”错误。在这个特殊上下文中的工作部分是这样的(几乎是完整的代码):

void Enunciado():
{}
{
前瞻(5)(Variavel()Expressao())|(Chamada_procedimento())|(Enunciado_composto())|(Expressao()Enunciado()Enunciado())|(Expressao()Enunciado())
}
void Variavel():
{}
{
前瞻(2)(|)(Expressao())
}
void Chamada_procedimento():
{}
{
前瞻(2)(|)(Lista_expressoes())
}
void Lista_expressoes():
{}
{
Expressao()列表a_expressoes2()
}
void Lista_expressoes2():
{}
{
(“,”Expressao()列表a_expressoes2())?
}
void Expressao():
{}
{
前瞻(2)Expressao_simples()| Expressao_simples()Expressao_simples()
}
void Expressao_simples():
{}
{
前瞻(3)(Termo()表达式简单化2())|(Sinal()Termo()表达式简单化2())
}
void Expressao_simples2():
{}
{
(Termo()表达式a_simples2())?
}
void Termo():
{}
{
Fator()术语2()
}
void Termo2():
{}
{
(Fator()Termo2())?
}
void Fator():
{}
{
前向(2)表
}
有人能找出错误在哪里?我已经尝试了很多东西,但是现在这个看起来对我很好(事实上不是这样)。 谢谢


编辑:具有相同名称,但最后带有数字2的函数用于消除左递归。

我没有这个特定的解析器/生成器可供测试, 但奇怪的是,解析器似乎在考虑
'='
作为一个标记。我会先调查一下。 如果这还不能揭示问题所在,那么下一步就要调查了 您对表达式的定义是否简单

恐怕调查这样的问题最简单的方法是 痛苦-要暂时将语法还原到最简单的情况,请参阅 如果解析器接受,如果接受,则展开语法并重新测试 直到你发现问题

换句话说,首先将程序定义为

PROGRAM : "a" "=" "b"
如果解析器接受这一点,请尝试

PROGRAM : IDENTIFIER "=" IDENTIFIER
然后

然后

最后,您应该找到导致问题的构造

我会说“祝你好运!”,但你并不真的需要它,只要有足够的耐心
和简单的测试用例。

我没有这个特定的解析器/生成器可供测试, 但奇怪的是,解析器似乎在考虑
'='
作为一个标记。我会先调查一下。 如果这还不能揭示问题所在,那么下一步就要调查了 您对表达式的定义是否简单

恐怕调查这样的问题最简单的方法是 痛苦-要暂时将语法还原到最简单的情况,请参阅 如果解析器接受,如果接受,则展开语法并重新测试 直到你发现问题

换句话说,首先将程序定义为

PROGRAM : "a" "=" "b"
如果解析器接受这一点,请尝试

PROGRAM : IDENTIFIER "=" IDENTIFIER
然后

然后

最后,您应该找到导致问题的构造

我会说“祝你好运!”,但你并不真的需要它,只要有足够的耐心
和简单的测试用例。

问题在于,您正在以一种不起作用的方式使用LOOKAHEAD。比如你有

  LOOKAHEAD(2)Expressao_simples()
| Expressao_simples() <OPERADOR_RELACIONAL> Expressao_simples()

将此代码与Pascal报告(修订版)中的图表进行比较

问题在于,您正在以一种根本不起作用的方式使用前瞻。比如你有

  LOOKAHEAD(2)Expressao_simples()
| Expressao_simples() <OPERADOR_RELACIONAL> Expressao_simples()

将此代码与Pascal报告(修订版)中的图表进行比较

也许它在Expressao中采用了短选项Expressao_simples(),而不是Expressao_simples()Expressao_simples()前瞻问题?。。或者纯粹基于errormessage的Expressao_simples()的终止子句。它需要一个简单的op(仍然在Expressaosimples()中)或THEN(表达式块的结尾)。也许它在Expressao中采用了短选项Expressao_simples(),而不是Expressao_simples()的前瞻问题?。。或者纯粹基于errormessage的Expressao_simples()的终止子句。它需要一个简单的操作(仍然在Expressaosimples()中)或(表达式块的结尾)。谢谢你的建议,这就是我将开始做的。这是一个痛苦的过程做现在,但必要的哈哈干杯!谢谢你的建议,这就是我要开始做的。这是一个痛苦的过程做现在,但必要的哈哈干杯!
  LOOKAHEAD(2)Expressao_simples()
| Expressao_simples() <OPERADOR_RELACIONAL> Expressao_simples()
Expressao_simples()
( 
    <OPERADOR_RELACIONAL> Expressao_simples()
)?