1

I have written an interpreter using ocamllex and ocamlyacc, the lexer and the parser work correctly but currently they only parse the last .txt argument it receives as oppose to all of them in turn. For example, ./interpret one.txt two.txt three.txt only parses three.txt as oppose to parsing one.txt and then two.txt and then three.txt which is what I want. So for example the parse results are as follows:

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

On calling ./interpret one.txt two.txt three.txt the current output is: 3 but I want it to be 123

Here is my main class which deals with the stdin and 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;

Thanks for your time

1 Answers1

1

There's not really enough code here to be able to help.

If I assume that the output is written by eval, then I see only one call to eval. But there's nothing here that deals with filenames from the command line, so it's hard to say more.

If you are planning to read input from files, then there's no reason to be using stdin for anything as far as I can tell.

(I know this is a very minor point, but this code doesn't constitute a class. Other languages use classes for everything, but this is a module.)

Update

Here's a module that works something like the Unix cat command; it writes out the contents of all the files from the command line one after the next.

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

Here's how it looks when you compile and run it.

$ ocamlc -o mycat mycat.ml
$ echo test line 1 > file1
$ echo test line 2 > file2
$ ./mycat file1 file2
test line 1
test line 2
Jeffrey Scofield
  • 65,646
  • 2
  • 72
  • 108
  • Hi Jeffrey, you are correct that eval produces the output, is there no way of "getting" each file argument from the command line (for example .get(1) would get the first file argument) and then I can all eval on that file, and then move onto the next? – user546482872 Mar 18 '17 at 19:18
  • so one.txt may contain the int "1" which is parsed as an int token and then eval produces the output for this token – user546482872 Mar 18 '17 at 19:25
  • I'll add some example code for processing filenames from the command line. – Jeffrey Scofield Mar 18 '17 at 19:33