2014-02-24 2 views
1

Ocaml의 클래스 컴파일러를 수행하고 있습니다. 나는 "1"과 같은 명령이나 표현식을 가진 파일을 읽을 필요가있다. 그런 다음 Int 1을 반환한다. 같은 코드는 나와 나와 나의 친구를 제외하고 전체 클래스와 함께 작업했다. 모두가 동일한 ocaml 버전과 우분투 13.04를 사용하고 있습니다. 오류는 다음과 같습니다. Lexico.EofOcaml의 오류

누군가가이 문제의 원인에 대해 알고 있습니까?

type opB = 
| Soma 
| Sub 
| Mul 
| Div 

type exp = 
| Int of int 
| Float of float 
| String of string 
| Char of char 
| Identificador of string 
| Bin of opB * exp * exp 

이 Sintatico.mly입니다 :

%{ 
open Asa;; 
%} 

%token <int> INT 
%token <float> FLOAT 
%token <string> STRING 
%token <char> CHAR 
%token <string> IDENTIFICADOR 
%token APAREN FPAREN PTVIRG 
%token MAIS MENOS MUL DIV 

%left MAIS MENOS 
%left MUL DIV 

%start main 
%type <Asa.exp> main 

%% 

main: expr     { $1 } 
; 

expr: IDENTIFICADOR   { Identificador($1) } 
| INT      { Int($1) } 
| FLOAT      { Float($1) } 
| STRING     { String($1) } 
| CHAR      { Char($1) } 
| APAREN expr FPAREN  { $2 } 
| expr MAIS expr   { Bin(Soma, $1, $3) } 
| expr MENOS expr   { Bin(Sub, $1, $3) } 
| expr MUL expr    { Bin(Mul, $1, $3) } 
| expr DIV expr    { Bin(Div, $1, $3) } 
; 

Lexico.mll :

{ 
open String 
open Sintatico 
exception Eof 
} 

let digito = ['0'-'9'] 
let caracter = [^ '\n' '\t' '\b' '\r' '\'' '\\'] 
let identificador = ['a'-'z' 'A'-'Z']['a'-'z' '0'-'9']* 

rule token = parse 
| [' ' '\t' '\n'] { token lexbuf } (* ignora os espacos *) 
| digito+ as inum { print_string " int "; INT (int_of_string inum) } 
| digito+'.'digito+ as fnum { print_string " float "; FLOAT (float_of_string fnum) } 
| '\"' ([^ '"']* as s) '\"' { print_string " string "; STRING (s)} 
| '\'' caracter '\'' as ch  { print_string " char "; CHAR (String.get ch 1) } 

| identificador as id  { print_string " identificador "; IDENTIFICADOR (id) } 

| '('    { print_string " abreparent "; APAREN } 
| ')'    { print_string " fechaparent "; FPAREN } 

| '+'    { print_string " + "; MAIS } 
| '-'    { print_string " - "; MENOS } 
| '*'    { print_string " * "; MUL } 
| '/'    { print_string "/"; DIV } 

| ';'       { print_string " ptv "; PTVIRG } 

| eof    { raise Eof } 

라는 이름의 파일 carregatudo.ml를 호출하는 코드 이것은 asa.ml입니다 is :

#load "asa.cmo" 
#load "sintatico.cmo" 
#load "lexico.cmo" 

open Asa;; 

let analisa_arquivo arquivo = 
let ic = open_in arquivo in 
let lexbuf = Lexing.from_channel ic in 
let asa = Sintatico.main Lexico.token lexbuf in 
close_in ic;  
asa 

소르 포르투갈어에 대한 Y :

CAMLC = ocamlc 
CAMLLEX = ocamllex 
CAMLYACC = ocamlyacc 

interpretador: asa.cmo sintatico.cmi sintatico.cmo lexico.cmo 

portugol: asa.cmo sintatico.cmi sintatico.cmo lexico.cmo principal.cmo 

clean: 
rm *.cmo *.cmi 

# regras genericas 
.SUFFIXES: .mll .mly .mli .ml .cmi .cmo .cmx 
.mll.mli: 
$(CAMLLEX) $< 
.mll.ml: 
$(CAMLLEX) $< 
.mly.mli: 
$(CAMLYACC) $< 
.mly.ml: 
$(CAMLYACC) $< 
.mli.cmi: 
$(CAMLC) -c $(FLAGS) $< 
.ml.cmo: 
$(CAMLC) -c $(FLAGS) $< 

그리고 다음 :

arquivo는 Lexico가

Sintatico 내가 interpretador을 명령을 사용하여이 메이크 파일을 실행할 수 있도록 파서

첫 번째를 의미 렉서

의미 파일을

을 의미한다 carregatudo.ml : #use "carregatudo.ml";;

다음 함수 : analisa_arquivo ("teste.pt") ;;

1 

및 반환은

Int 1 

해야하지만

감사합니다 Lexico.Eof 오류가 계속 :

입력 파일 teste.pt 같은입니다!

+0

너무 적은 정보만으로는 도움이되지 않습니다. 보고 된 오류의 의미가 명확하지 않습니다. 그것은 예외입니까? 실제 오류는'Lexico.Eof'입니까? 당신의 코드에서 언급 된'Lexer' 모듈이 없습니다. (포르투갈어는별로 문제가되지 않으며, 일관된 이름 지정이 절대적으로 필요합니다 :-) –

+0

이제 문제는 더 잘 설명됩니다. Eof는 예외이며 Lexico.Eof는 오류입니다. – MDayrell

답변

1

재귀 규칙이 일치하는지 확인하기 위해 파서가 두 개 이상의 토큰을 소비하고 있는데, 이는 매우 자연스럽게 Eof이 발생하도록합니다. 기본적으로 파서는 파일의 끝 부분을 실행하고 있습니다. 왜냐하면 표현의 더 많은 부분을 찾을 필요가 없을 때 알려주는 규칙이 없기 때문입니다.

쉽게 수정 문법에 그에 대한 Eof 토큰 END_OF_INPUT에 대한 예외와 일치를 변경하는 것입니다 :

main: expr END_OF_INPUT { $1 } 

가 또는 당신은 ;로 명시 적 종료를 소개 할 수있다.

+0

그게 다야!고맙습니다! – MDayrell