LINUX.ORG.RU

Вопрос по компиляторам/трансляторам

 ,


0

1

Вопрос по транслятору, не знаю в какую ветку задать вопрос, если что, простите…

Приветствую всех, вопрос такой, есть транслятор в байт код самодельного языка на базе паскаля, на винде. Задача: переписать этот транслятор на юникс, с сохранением поддержки старых проектов с винды.

Столкнулся с проблемой кодировок, на юниксе кодировка utf-8, на винде кодировка CP1251, транслятор написан на основе лексического анализатора flex, он не понимает unicode, для него должно быть один символ - один байт, соответственно если текст в кодировке utf-8, он не понимает ничего. В данный момент я костылю перекодированием с помощью iconv, но чую что это дичь))

Прошу совета, стоит ли переписывать транслятор на новый анализатор, погуглил, есть re-flex и типо он подерживает все старые команды из flex, то есть по сути ничего особо переписывать и не нужно будет, но чет я не уверен))

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

Добавлю еще, что на эту работу (на перекат на новый анализатор) мне выделят месяц, максимум, полтора, если кто то знает подводные камни, буду рад советам.

Спасибо!



Последнее исправление: lazgo (всего исправлений: 2)
Ответ на: комментарий от AndreyKl

так я уже там полгода работаю и уже въехал, как все работает, плюс есть бекграунд в виде книжки про компиляторы, так что с пониманием происходящего все ок))

lazgo
() автор топика
Ответ на: комментарий от lazgo

есть транслятор в байт код самодельного языка на базе паскаля,

а он есть в каком виде? исходники? описание?

PS тексты программ с оффтопика перекодировать ВСЕ РАВНО придется, так или иначе

anonymous
()
Ответ на: комментарий от LightDiver

там есть еще библиотека функций, типо как в с++ stl, и там есть типо файлы, которые описывают функции, и они не просто файлы, а бинарные, в них структуры записаны, и текст в струтктурах тоже в CP1251. Там просто как снежный ком катитться на меня, и я незнаю че с этим делать)))

lazgo
() автор топика
Ответ на: комментарий от AndreyKl

Ой, чего там въезжать с современными ИИ. Проблема решается просто перекодированием файла в ср1251. Если очень хочется заморочиться, gsub("[\128-\255][\128-\255]) (луа, но суть думаю понятна). Не думаю что у него есть еще и на каком нибудь китайском операторы, а отловить кириллицу и латиницу и распознат это дело одной функции-однострочника.

LightDiver ★★★★★
()

По моему личному опыту (в свое время сделал интерпретатор простенького языка в академических целях) лексер и парсер языка с контекстно-независимой грамматикой довольно просто реализуются вручную, при этом такое решение даже будет гибче. Если хочется мнения, повесомее, чем от анонимуса с LOR, то Walter Bright (создатель первого компилятора C++ и языка D) высказывался в аналогичном ключе (см. раздел Implementation).

Вроде бы для парсинга Паскалеподобного языка не нужен большой lookahead (как для C), так что с дивана кажется, что рекурсивного нисходящего парсера в твоем случае может быть достаточно (а он довольно прост в реализации вручную).

Если бы это был хобби-проект, я бы однозначно посоветовал попробовать написать свой парсер. Но при наличии жестких сроков и отсутствии опыта, лучше основательно взвесить все риски. Хотя костыль у тебя уже есть и, я так понял, работает. Т.е. ты особо ничем не рискуешь.

m0rph ★★★★★
()
Последнее исправление: m0rph (всего исправлений: 2)
Ответ на: комментарий от m0rph

А не проще пропускать текст через функцию конвертор? Берем ютф и скармливаем в том виде текст, в котором нужно. Собственно все. И не нужно ничего переделывать. Или я что то упускаю?

LightDiver ★★★★★
()

эту работу (на перекат на новый анализатор) мне выделят месяц, максимум, полтора

Какой там объем кода? Ты начни делать, и через несколько дней поймёшь, хватит тебе месяца или нет.

rupert ★★★★★
()
Ответ на: комментарий от m0rph

костыль работает, да, но оставлять такую хурню в релиз я не хочу, и статью читал, и там все круто, но суть в том, что это уже все написно до меня, и на винде все работает, проблема чисто в кодировке, если лексер не понимает символы, он ничего не скомпилирует, и вы мне предлагаете написать свой лексер? или что? не понял, изаините…

lazgo
() автор топика

В данный момент я костылю перекодированием с помощью iconv, но чую что это дичь))

Почему? У тебя основная проблема в том что нужно просто кушать исходники в кодировке отличной от utf-8, и вся задача сводится к просто к условию, если на входе CP1251 сконвертировать в utf-8 и передать дальше. Всё =)

При этом это частный случай, можно не тянуть iconv, а просто сделать свой маленький преобразователь.

или дальше костылить с перекодировкой строк.

Это не костыль, ОС много разных если несколько ОС являются целевыми, то ты не костылишь, а учитываешь платформенные особенности источников исходного кода, даже более того, у тебя заявлена явная обратная совместимость, так что это даже не учёт.

Внутри твоей реализации будет одна единственная кодировка с которой всё работает, внешнее к ней приводится если то требуется.


Я не спец, просто мимокрокодил

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 1)
Ответ на: комментарий от LightDiver

Автор и написал, что подобный костыль он уже реализовал. Просто у него парсер работает в CP-1251, а в UTF-8 ему на вход могут в теории подать например emoji или вообще китайский - конвертер это не прожует.

m0rph ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Причем свой маленький преобразователь делается в рамках самой софтины без сторонних зависимостей. Я ж в луа 3 года так работаю - давно себе всю работу с ютф переписал. Оказалось - вообще не сложно. Простейшая структура же.

LightDiver ★★★★★
()
Ответ на: комментарий от LightDiver

У него сам язык, ключевые слова языка в кодировке CP1251, не просто написаны и файл сохранён так, а прям именно что конкретно язык такой. Я тоже думал сначала что просто текст как данные преобразовать и всё. Но нет. Ну значит либо делать ему две реализации, так как заявлена обратная совместимость.

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от lazgo

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

m0rph ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Подожди. У него ср1251, в рамках которой эмодзи и всякие китайские не существуют. Тогда в чем проблема? Делаем простейший конвертор подходящих нам символов. Используем их. Остальное не в нашей компетенции в принципе и тут уже можно думать что с ними делать. Или отсеивать или заменять.

LightDiver ★★★★★
()
Ответ на: комментарий от lazgo

Опиши что произойдет, если тебе подсунут текст на китайском, например? В рамках ср1251 такого быть не может чисто физически, например. Как ты его должен обработать? Мне уже интересно просто стало.

LightDiver ★★★★★
()

сурьезные дядьки пишут свой лексер, и занимает он строк несколько сот. ну в районе 500-600 и меньше.

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

если знать как писать, ну это дня три на расслабоне.

найди в инете как пишутся лексеры, их в гитхабе наверняка немеряно.

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

поскольку будет уникод, то нужно брать wide_char.

карочи берешь в гитхабе любой лексер, что работает с wchar, лучше проверенный с многими звездами и прикручиваешь его себе.

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

если начать нубу вот прям с нуля… ну за пару недель, при плохом раскладе, можно уложиться. но ждать не стоит, поскольку лучше сделать раньше на расслабоне, чем потом торопиться и провалить дело.

и не ругайся матом.

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от alysnix

карочи берешь в гитхабе любой лексер, что работает с wchar, лучше проверенный с многими звездами и прикручиваешь его себе.

там, помнится, один прикрутил freeradius )

anonymous
()
Ответ на: комментарий от lazgo

Я тут поэкспериментировал на раст. Если вручную обрабатывать, то там разница практически незаметна:

--- Test: ASCII ---
Read UTF-8 directly: 2.136ms
Convert with encoding_rs: 2.622ms
Fast byte-level conversion: 6.482ms
Convert with iconv: 9.450ms

--- Test: Cyrillic ---
Read UTF-8 directly: 2.906ms
Convert with encoding_rs: 35.093ms
Fast byte-level conversion: 2.892ms
Convert with iconv: 7.831ms

--- Test: Mixed ---
Read UTF-8 directly: 1.368ms
Convert with encoding_rs: 17.427ms
Fast byte-level conversion: 2.782ms
iconv warning: "iconv: недопустимая входная последовательность в позиции 12240\n"
Convert with iconv: 819.765µs

--- Test: Emoji ---
Read UTF-8 directly: 2.512ms
Convert with encoding_rs: 71.829ms
Fast byte-level conversion: 7.765ms
iconv warning: "iconv: недопустимая входная последовательность в позиции 30192\n"
Convert with iconv: 976.654µs

--- Test: Digits ---
Read UTF-8 directly: 146.420µs
Convert with encoding_rs: 232.213µs
Fast byte-level conversion: 1.578ms
Convert with iconv: 4.277ms

--- Test: Punctuation ---
Read UTF-8 directly: 126.472µs
Convert with encoding_rs: 218.345µs
Fast byte-level conversion: 1.495ms
Convert with iconv: 4.230ms

--- Test: Long words ---
Read UTF-8 directly: 301.526µs
Convert with encoding_rs: 469.201µs
Fast byte-level conversion: 2.761ms
Convert with iconv: 7.348ms

--- Test: All together ---
Read UTF-8 directly: 2.972ms
Convert with encoding_rs: 43.406ms
Fast byte-level conversion: 6.322ms
iconv warning: "iconv: недопустимая входная последовательность в позиции 12528\n"
Convert with iconv: 891.437µs

--- Test: Empty ---
Read UTF-8 directly: 5.047µs
Convert with encoding_rs: 3.565µs
Fast byte-level conversion: 2.996µs
Convert with iconv: 566.670µs

--- Test: Very long line ---
Read UTF-8 directly: 99.324µs
Convert with encoding_rs: 210.339µs
Fast byte-level conversion: 1.384ms
Convert with iconv: 3.956ms

«В разы», да - но не в 260 раз уже.

LightDiver ★★★★★
()
Последнее исправление: LightDiver (всего исправлений: 1)
Ответ на: комментарий от James_Holden

в данный момент это и работает на вайне, и у всех производителей скад это только в вайне, мыже хотим типо первую нативнуйю реализацию, без вайна. И щас все активно юзают библиотеку open62541, они наверное в шоке, сколько у них форков)) И с вайном так же, наши ребята уже 5 багов в вайне пофиксили, связаные с gdi

lazgo
() автор топика