2016-01-24 3 views
1

Как часть курса Compiler Principles, который я беру в своем университете, мы пишем компилятор, который реализован в OCaml, который компилирует код схемы в CISC-подобную сборку (которая это просто макросы C). основная работа компилятора такова:Ограничение длины строки OCaml при чтении из stdin file

  1. Почитаю *.scm файл и преобразовать его в OCaml string.
  2. Разберите строку и выполните различные анализы.
  3. Запустите генератор кода на выходе AST из семантического анализатора, который выводит текст в файл *.c.
  4. Скомпилируйте этот файл с помощью GCC и запустите его в терминале.

Ну, все хорошо и хорошо, кроме этого: Я пытаюсь прочитать файл ввода, который длинно около 4000 строк, и в основном один огромный выражения, что это смесь схемы if & and. Я выполняю компилятор через utop. Когда я пытаюсь прочитать входной файл, я сразу получаю сообщение об ошибке переполнения стека. Поначалу я предполагаю, что для OCaml этот файл просто для больших, но я не смог найти документацию, которая бы поддерживала эту теорию.

Любые предложения?

+0

Вы могли бы предоставить только кусок кода, который читает файл? вы пытались уменьшить свой код, чтобы показать проблему? –

+0

см. Http: // stackoverflow.com/questions/5774934/how-do-i-read-in-lines-from-a-text-file-in-ocaml; Мне удалось прочитать файл размером 2 МБ с 4000 л в utop без каких-либо проблем. –

+1

Я угадываю, но у этого есть все симптомы использования функции без хвоста-рекурсии для чтения файла. Однако, без реального кода, это невозможно сказать. –

ответ

0

Ну, оказывается, что ограничение было равным максимальному значению, установленному OCaml для использования.

Я побежал следующую команду в терминале, чтобы увеличить квоту:

export OCAMLRUNPARAM="l=5555555555"

Это работало как шарм - мне удалось прочитать и скомпилировать файл ввод практически мгновенно.

Для справочных целей, это код, который считывает файл:

let file_to_string input_file = 
    let in_channel = open_in input_file in 
    let rec run() = 
    try 
     let ch = input_char in_channel in ch :: (run()) 
    with End_of_file -> 
     (close_in in_channel; 
     []) 
    in list_to_string (run());; 

где list_to_string является:

let list_to_string s = 
    let rec loop s n = 
    match s with 
    | [] -> String.make n '?' 
    | car :: cdr -> 
     let result = loop cdr (n + 1) in 
     String.set result n car; 
     result 
    in 
    loop s 0;; 

Самое смешное - я писал file_to_string в хвостовой рекурсии. Это предотвратило переполнение стека, но почему-то перешло в бесконечный цикл. О, хорошо ...

1

Максимальная длина строки указана в Sys.max_string_length. Для 32-битной системы это довольно коротко: 16777211. Для 64-битной системы это 144115188075855863.

Если вы не используете 32-разрядную систему, а ваш 4000-строчный файл превышает 16 МБ, Не думайте, что вы нажимаете ограничение длины строки.

Переполнение стека не то, что вы ожидаете увидеть, когда строка слишком длинная.

Скорее всего, у вас бесконечная рекурсия или, возможно, очень глубокое вложенное вычисление.

 Смежные вопросы

  • Нет связанных вопросов^_^