2014-02-24 68 views
1

我正在爲Ocaml中的類做一個編譯器。我需要用命令或表達式來讀取文件,比如「1」,然後它返回Int 1。除了我和我的朋友之外,相同的代碼與整個班級一起工作。每個人都使用相同的ocaml版本和Ubuntu 13.04。錯誤是:Lexico.Eof錯誤EOF Ocaml

有人對這可能是什麼有什麼想法? 這是asa.ml:

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文件命名是:

#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 

Sorr關於葡萄牙Y:

arquivo意味着文件

詞曲意味着詞法

Sintatico意味着分析器

首先,我用命令來運行這個Makefile使interpretador:

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

而旁邊carregatudo.ml:#use「carregatudo.ml」;;

接下來的函數:analisa_arquivo(「teste.pt」);;

輸入文件teste.pt是這樣的:

1 

和回報應該是

Int 1 

但我不斷收到錯誤Lexico.Eof

謝謝!

+0

這麼少的信息很難提供幫助。甚至不清楚你報告的錯誤的含義。這是一個例外嗎?實際的錯誤是「Lexico.Eof」?代碼中沒有提到名爲'Lexer'的模塊。 (葡萄牙語不是一個問題;一致的命名是絕對必要的:-) –

+0

我認爲現在這個問題更好地解釋。 Eof是一個例外,而Lexico.Eof是錯誤。 – MDayrell

回答

1

解析器消耗多個標記以查看遞歸規則是否匹配,這很自然地會導致Eof被引發。基本上你的解析器在文件的末尾運行,因爲它缺乏任何規則來告訴它什麼時候停止查找表達式的更多部分。

一個簡單的辦法是改變Eof例外的令牌END_OF_INPUT,和對陣,在語法:

main: expr END_OF_INPUT { $1 } 

另外,您可以引入一個明確的終止,如;

+0

就是這樣!謝謝! – MDayrell