2017-03-18 5 views
0

J'ai écrit un interpréteur en utilisant ocamllex et ocamlyacc, le lexer et l'analyseur fonctionnent correctement mais actuellement ils n'analysent que le dernier argument .txt qu'il reçoit comme opposé à tous eux à leur tour. Par exemple, ./interpret one.txt two.txt three.txt analyse uniquement three.txt en opposition à l'analyse one.txt puis two.txt puis three.txt, ce qui correspond à ce que je souhaite. Ainsi, par exemple les résultats parse sont les suivants:OCAML Prenant plusieurs arguments de stdin et fonctionnant dessus un par un

one.txt -> "1" 
two.txt -> "2" 
three.txt -> "3" 

En appelant ./interpret one.txt two.txt three.txt la sortie actuelle est: 3 mais je veux que ce soit 123

Voici ma classe principale qui traite de la stdin et stdout

open Lexer 
open Parser 
open Arg 
open Printf 

let toParse c = 
    try let lexbuf = Lexing.from_channel c in 
      parser_main lexer_main lexbuf 
    with Parsing.Parse_error -> failwith "Parse failure!" ;; 


let argument = ref stdin in           
let prog p = argument := open_in p in 
let usage = "./interpreter FILE" in 
parse [] prog usage ; 
let parsed = toParse !argument in 
let result = eval parsed in 
let _ = parsed in 
flush stdout; 

Merci pour votre temps

Répondre

1

Ther Ce n'est pas vraiment assez de code ici pour pouvoir aider. Si je suppose que la sortie est écrite par eval, alors je vois un seul appel à eval. Mais il n'y a rien ici qui traite des noms de fichiers à partir de la ligne de commande, il est donc difficile d'en dire plus.

Si vous envisagez de lire des entrées à partir de fichiers, il n'y a aucune raison d'utiliser stdin pour tout ce que je peux dire.

(Je sais que ce point est très mineur, mais ce code ne constitue pas une classe. D'autres langues utilisent des classes pour tout, mais c'est un module.)

Mise à jour

Voilà un module qui fonctionne quelque chose comme la commande chat Unix; il écrit le contenu de tous les fichiers de la ligne de commande l'un après l'autre.

let cat() = 
    for i = 1 to Array.length Sys.argv - 1 do 
     let ic = open_in Sys.argv.(i) in 
     let rec loop() = 
      match input_line ic with 
      | line -> output_string stdout (line^"\n"); loop() 
      | exception End_of_file ->() 
     in 
     loop(); 
     close_in ic 
    done 

let() = cat() 

Voici à quoi il ressemble lorsque vous le compilez et l'exécutez.

$ ocamlc -o mycat mycat.ml 
$ echo test line 1 > file1 
$ echo test line 2 > file2 
$ ./mycat file1 file2 
test line 1 
test line 2 
+0

Salut Jeffrey, vous avez raison que eval produit la sortie, est-il aucun moyen de « obtenir » chaque argument de fichier à partir de la ligne de commande (par exemple .get (1) obtiendrait le premier argument de fichier), puis Je peux tous évaluer sur ce dossier, puis passer à la suivante? – user546482872

+0

donc one.txt peut contenir l'int "1" qui est analysé comme un jeton int et ensuite eval produit la sortie pour ce jeton – user546482872

+0

Je vais ajouter un exemple de code pour le traitement des noms de fichiers à partir de la ligne de commande. –