2017-11-29 5 views
0

파스칼 하위 세트에 대한 파서를 작성하기 위해 Javacc과 협력하고 있습니다. Javacc 파서 생성기가 제 언어를 인식하지 못합니다 (입력)

내 코드입니다 :

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>) 
} 

그리고 이것은 입력 프로그램입니다 :

문제가
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) 

, 나는 이해할 수 없다 :

program exemplo (input, output, test); 
var x, y: integer; 
function mdc (a, b: integer): integer; 
begin 
    if b = 0 then mdc := a 
    else mdc := mdc (b, a mod b) 
end; 

begin 
    read(x, y); 
    write(mdc(x,y)); 
end; 

JavaCC에이 반환 왜 Javacc는 그 주장을 기대하고 있으며 그가 그 위치에 "="잘못을 부른 것입니다.

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()) 
} 

누군가가 오류가 어디 알아낼 수 :이 especific 상황에 직장에서 부분이 하나의 (거의 전체 코드)인가? 나는 많은 것을 시도했지만이 권리는 이제 나에게 좋게 보인다 (실제로는 그렇지 않다). 감사합니다. .

편집 : 동일한 이름이지만 최종 번호가 2 인 함수는 왼쪽 재귀를 제거하기 위해 만들어집니다.

+0

은 아마 어떻게 든 Expressao의이 짧은 옵션 대신 Expressao_simples의 Expressao_simples을()() 소요 Expressao_simples() 내다 문제? .. 또는 Expressao_simples의 종료 절() 즉,이 순전히으로 ErrorMessage를 기반으로 . 그것은 간단한 op (여전히 Expressaosimples()) 또는 THEN (표현 블록의 끝)을 기대합니다. –

답변

1

나는, 을 테스트하기 위해 사용할 수있는이 특정 파서/발전기가 없습니다하지만 파서 가 하나의 토큰으로 '= ' 에 관한 것으로을 보인다 이상한 것 같다. 나는 그것을 먼저 조사 할 것이다. 그래도 문제가 발견되지 않으면 을 조사 할 다음 질문은 Expressao_simples입니다.

나는이 약간에게처럼 가장 쉬운 방법은 문제를 조사 할 것을 두려워 고통스러운 - 일시적으로는 않는 경우, 확장 파서가 그것을 받아들이는 경우 을보고, 가장 간단한 경우에 문법을 다시 제거하기 문제를 확인하기 전까지 문법 및 을 다시 테스트하십시오. 파서가,

PROGRAM : IDENTIFIER "=" IDENTIFIER 

다음

PROGRAM : IDENTIFIER RELATIONALOPERATOR IDENTIFIER 

다음

PROGRAM : SIMPLEEXPRESSION RELATIONALOPERATOR SIMPLEEXPRESSION 
,536을 시도 할 것으로 받아들이는 경우 즉

,

PROGRAM : "a" "=" "b" 

으로 프로그램을 정의하여 시작

등 결국에는 문제를 일으키는 구성 요소를 찾아야합니다.

나는 "행운을 빌어 요!"라고 말하고 싶지만 실제로는 필요하지 않습니다. 단지 인내가 많이 있습니다. 간단한 테스트 케이스.

+0

당신의 sugestion 주셔서 감사합니다, 그게 내가 할 것입니다. 이제는 할 수있는 고통스러운 일이지만, 필요한 건 하아! –

2

문제는 LOOKAHEAD가 작동하지 않는 방식으로 사용하고 있다는 것입니다. 예를 들어, 당신은

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

SO이 입력의 다음의 2 토큰, Expressao_simples이 첫 번째 대안을 함께 일치, 그렇지 않으면 두 번째 대안을 가지고 있다고 말한다 있습니다.두 번째 대안이 성공할 수있는 모든 상황에서 분명히 다음 두 개의 토큰이 첫 번째 대안과 일관성이 있으므로 첫 번째 대안이 선택됩니다.

대신 당신은 파스칼 보고서에서 그림을이 코드를 비교하여 나중에

Expressao_simples() 
( 
    <OPERADOR_RELACIONAL> Expressao_simples() 
)? 

때까지 검색을 지연시킬 수 있습니다 (개정). enter image description here

관련 문제