Feb. 10th, 2010

thedeemon: (Default)
Кто-то из мэтров, вроде Хейлсберга, говорил, что сложность развития компиляторов квадратичная: если уже есть N фич и нужно добавить еще одну, приходится продумывать и аккуратно реализовывать взаимодействие новой фичи со всеми N старыми. Не берусь пока это подтвердить или опровергнуть, но в моем случае добавление в Leo структур привело к серьезному рефакторингу модулей Leo и LeoC: косяки исходной реализации стали выпирать и мешаться слишком сильно, пришлось исправлять. В итоге общий размер исходников увеличился всего на 7 строк: небольшой рост модулей парсинга и LeoC был компенсирован заметным сокращением и упрощением модуля Leo в ходе рефакторинга.

Структуры мне нужны для более удобного взаимодействия кода на Leo с кодом программы-хоста. Выглядит это так:
type point = { x : int; y : int }

type indata = {
 len : int
 str : byte[len] # кстати, это похоже на частный случай зависимых типов ;)
 ints : int[10]
 p : point
 out : byte[len]
}
 
args : indata
args.p.x <- 50; args.p.y <- 60

for i in args.ints.range  args.ints[i] <- i+1 end

for i in args.str.range
 args.out[i] <- args.str[|args.str| - 1 - i]
end
args - имя входного параметра программы на Leo (наподобие argc и argv).

В процессе тестирования всплыла очень смешная ошибка: описанный тут метод разбора делал арифметические операции правоассоциативными, в результате чего выражение 3 - 1 - 1 разбиралось как 3 - (1 - 1). Получилось так в ходе борьбы с левой рекурсией в грамматике, правило для сумм и разностей выглядело как
E = P + E | P - E | P
Если поменять местами P и E, ассоциативность станет нормальной, но возникнет левая рекурсия, что недопустимо. Проблема была решена путем преобразования таких правил в форму
E = P (+ P | - P)*
Что в коде выглядит как:
and expr_r s = ( 
  product >>= fun e1 ->  p_seq0  
    ((tok Lplus >>> product >>= fun e2 -> return (Add, e2)) |||  
     (tok Lminus >>> product >>= fun e2 -> return (Sub, e2)))  
    >>= fun ps -> return (List.fold_left (fun e1 (op, e2) -> Leo.Arith(op, e1, e2)) e1 ps) 
  ) s 
Аналогично для делений с умножениями.


Дальше: оптимизация.

Profile

thedeemon: (Default)
Dmitry Popov

July 2025

S M T W T F S
  12345
6789101112
13141516171819
20212223242526
27282930 31  

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Aug. 21st, 2025 09:58 pm
Powered by Dreamwidth Studios