LINUX.ORG.RU

Интерпретатор языка высокого уровня в машинный код


0

2

Дали тему курсовой работы «Интерпретатор языка высокого уровня в машинный код», которую нужно написать на С++. Насколько я понял машинный код это двоичная система счисления. Посоветуйте с чего начать, может план работы или литературой (желательно русскую) .

Зарание спасибо!

Ответ на: комментарий от Deleted

Тут дело в том, что при компиляции используются одни алгоритмы («книгу дракона» не читал, но могу предполагать, просто по её названию, что там речь идёт в основном о них), а при декомпиляции (с востановлением высокоуровневых конструкций вроде if, циклов и функций) - совсем другие. То определение это определение транлятора вообще (тогда как compiler, decompiler, assembler, disassembler, rewriter это всё частные случаи, когда делаются допущения про форму того из чего и во что производится трансляция).

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

То определение

Учитывая, что «тип» и «язык» понятия эквивалентные, это описание применимо к любым функциям вообще.

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

Тут дело в том, что при компиляции используются одни алгоритмы («книгу дракона» не читал, но могу предполагать, просто по её названию, что там речь идёт в основном о них), а при декомпиляции (с востановлением высокоуровневых конструкций вроде if, циклов и функций) - совсем другие.

А при компиляции ассемблера, форта и прочих - третьи (потому, что большинство того, что писано в книге дракона - это для них с пушки по воробью). От этого суть не меняется: на вход дали одно представление, на выходе получили другое, эквивалентное ему.

compiler, decompiler, assembler, disassembler, rewriter это всё частные случаи, когда делаются допущения про форму того из чего и во что производится трансляция

Определи в таком случае, что значит «компилятор».

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

Определи в таком случае, что значит «компилятор»

Под определение geekless подходит функция length, например, — программы на языке строк переводит в программы на языке чисел. Если compile : A → B, то я бы дополнил язык A функцией eval : A → Result, язык B функцией exec : B → Result и потребовал доказуемости теоремы:

∀(e : A). exec (compile e) = eval e

т.е. компиляция может (или должна, чтобы называться компиляцией?) стирать синтаксическую структуру, но должна сохранять смысл (length — компилятор, если eval = length, exec = id, если требовать eval ≠ compile, B ≠ Result, exec ≠ id, то нет). Может ли компиляция востанавлявать структуру? Не знаю, мне называние декомпилятора компилятором режет слух.

Пусть язык это тип:

Lang : Set

Интерпретатор будем задавать в виде функции Lang → Value, где Value — язык (тип) значений (иногда = Lang). Для этой цели зададим семантические скобки:

record ⟦_⟶_⟧ (A B : Set) : Set where
  constructor denote
  field ⟦_⟧ : A → B

⟦_⟧ : {A B : Set} → ⦃ _ : ⟦ A ⟶ B ⟧ ⦄ → A → B
⟦_⟧ ⦃ f ⦄ = ⟦_⟶_⟧.⟦_⟧ f

Пусть VM — тип, выполнение программы VM — функция Prog × VM → VM (либо state transformer с one-step, либо обычная функция, сразу за big-step), соответсвующие скобки:

record ⟪_⟫_⟶_ (A B C : Set) : Set where
  constructor denote
  field ⟪_⟫_ : A → B → C

⟪_⟫_ : {A B C : Set} → ⦃ _ : ⟪ A ⟫ B ⟶ C ⦄ → A → B → C
⟪_⟫_ ⦃ f ⦄ = ⟪_⟫_⟶_.⟪_⟫_ f

Компилятор — функция Lang → Prog.

Пример. Язык арифметических выражений:

data BinOp : Set where
  ∣+∣ : BinOp
  ∣×∣ : BinOp

data Expr : Set where
  nat : ℕ → Expr
  bop : BinOp → Expr → Expr → Expr

infixl 6 _+_
infixl 7 _×_

_+_ : Expr → Expr → Expr
_+_ = bop ∣+∣

_×_ : Expr → Expr → Expr
_×_ = bop ∣×∣

Его интерпретатор:

op : ⟦ BinOp ⟶ (ℕ → ℕ → ℕ) ⟧
op = denote case where
  case : BinOp → ℕ → ℕ → ℕ
  case ∣+∣ = _+ℕ_
  case ∣×∣ = _×ℕ_

eval : ⟦ Expr ⟶ ℕ ⟧
eval = denote case where
  case : Expr → ℕ
  case (nat n) = n
  case (bop f a b) = ⟦ f ⟧ (case a) (case b)

Язык стековой VM:

data Inst : Set where
  nat : ℕ → Inst
  bop : BinOp → Inst

Stack = List ℕ

Prog = List Inst

Функция выполнения для VM:

inst : ⟪ Inst ⟫ Stack ⟶ Stack
inst = denote case where
  case : Inst → Stack → Stack
  case (nat n) s = n ∷ s
  case (bop f) (a ∷ b ∷ s′) = ⟦ f ⟧ a b ∷ s′
  case _ _ = []

exec : ⟪ Prog ⟫ Stack ⟶ Stack
exec = denote case where
  case : Prog → Stack → Stack
  case [] s = s
  case (i ∷ p′) s with ⟪ i ⟫ s
  ... | [] = []
  ... | s′ = case p′ s′

Компилятор из языка в VM:

compile : ⟦ Expr ⟶ Prog ⟧
compile = denote case where
  case : Expr → Prog
  case (nat n) = [ nat n ]
  case (bop f a b) = case a ++ case b ++ [ bop f ]

Тест:

testExpr : Expr
testExpr = (nat 2 + nat 2) × nat 7

testEval : ℕ
testEval = ⟦ testExpr ⟧

testCompile : Prog
testCompile = ⟦ testExpr ⟧

testRun : Stack
testRun = ⟪ testCompile ⟫ []

-- testEval => 28
-- testRun => 28 ∷ []

Теорему

compiler-correct-theorem : (e : Expr) → exec (compile e) [] ≡ eval e ∷ []

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

quasimoto ★★★★
()

Не слушай ты этих «гениев». Найди книжку Шилдта по C или С++. Там он предлагает пример простого интертрепатора BASICa. Почитай, разберись - больше тебе и не надо. А то они тут насоветуют «драгон буков».

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

Тупой? ТСу как минимум компилятор нужен, если не суперкомпилятор. А ты тут с щилдтом убогим.

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

Главное что он там есть, этот результат, а значит и компилятор тоже.

Это он сам для себя внутри может быть компилятором. А для пользователя это интерпретатор.

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

а при декомпиляции (с востановлением высокоуровневых конструкций вроде if, циклов и функций) - совсем другие

Определение циклов — вполне себе задача, которую нужно решать для успешной оптимизации, например. При чем, имеются ввиду именно циклы в «лапше» произвольного графа для алгоритма, а не циклы как конструкты языка. Так что не всё так однозначно.

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

Под определение geekless подходит функция length, например, — программы на языке строк переводит в программы на языке чисел.

Твой «язык чисел» не является ЯП.

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

Твой «язык чисел» не является ЯП

Про ЯП ничего не было сказано - только про программы (термы?) и языки (что это?). Если языки это ЯП (что такое ЯП?), а программы - не просто термы, а некие выполнимые (на чём?) термы, то всё ок.

Нет. Результат не является эквивалентной программой.

Почему нет? Если программа на Си имеет некий смысл, после её компиляции получается, например, ассемблер визуально ничем не похожий на исходную программу, но имеющий тот же смысл, и при его декомпиляции обратно в Си опять получается программа визуально не похожая на исходный Си, но имеющая опять тот же смысл (всё три программы имеют один и тот же эффект от своего выполнения).

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

А для пользователя это интерпретатор.

Потому что пользователь не может почитать ассемблер / машинный код какой-то там функции? Он может это сделать. Он просто не может этот код как-то использовать - он зависит от рантайма сильно, линкера на него нет и т.п.

Собрать JS программу как stand-alone executable тоже можно, просто это будет большой executable вместе со всем рантаймом, так же как образ SBCL, например (там тоже можно прочесть ассемблер / машинный код функции, но вытащить этот код из рантайма проблематично).

quasimoto ★★★★
()

Посоветуйте с чего начать

С бега, подтягиваний, отжиманий и прочих упражнений для общей физической подготовки. Судя по поставновке вопроса, ты поступил туда, где не можешь и не хочешь учиться. Зачем мучать себя и, упаси хосспати, госбюджет?

red_eyed_peguin
()
Ответ на: комментарий от quasimoto

Про ЯП ничего не было сказано - только про программы (термы?) и языки (что это?). Если языки это ЯП (что такое ЯП?), а программы - не просто термы, а некие выполнимые (на чём?) термы, то всё ок.

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

А «термы и языки вообще» ты сколько угодно рассматривай в рамках формальных грамматик.

Так что «выполнимые», да.

выполнимые (на чём?)

Исполнителем. Есть такое понятие в теории.

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

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

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

Потому что пользователь не может почитать ассемблер / машинный код какой-то там функции?

Потому что см. определение. Я человек резкий, я не знаю, что тут ответить, чтоб меня потом не обвинили в переходе на личности...

Ну ок, давай сначала. Компилятор — это средство для перевода алгоритма из одной знаковой системы в другую. Ты используешь интерпретатор для перевода? Нет? Не используешь? И такого понятия как «целевой язык» у него даже нет? Вот видишь: это не компилятор!

А что такое интерпретатор? Внезапно — это исполнитель. Тот самый, из теории, без которого ЯП не имеет смысла. Что является результатом его работы? Результатом его работы является поведение — выполнение алгоритма.

Весь остальной твой бред про рантайм — это, извини, бред и есть. Забудь про рантайм. У тебя есть формальная знаковая система, для которой определена семантика выполнения, и есть исполнитель, который соответствует этой системе. Всё остальное — это скучная реальность бородатых красноглазых инженеров. Если я буду исполнять JS при помощи ручки и бумажки, я буду являться точно таким же исполнителем как тот, что входит в состав фирефокса. И никакого «рантайма» у меня нет.

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

(всё три программы имеют один и тот же эффект от своего выполнения).

Таких декомпиляторов нет в природе. Если бы были, то их можно было бы называть компиляторами из машинного кода в C (но их нет и не будет) :)

Про ЯП ничего не было сказано - только про программы (термы?) и языки (что это?).

Программа - это записанный при помощи знаковой системы алгоритм. Язык - эта самая система. Исполняется исполнителем. Не занимайся попытками демагогии.

Термы - это элементы некой формальной грамматики. Строго говоря, программа необязательна должна записываться на языке, описываемом контекстно-свободной грамматикой, хотя таковой является большинство языков (из популярных, не описываемых КС-грамматикой - C++).

Deleted
()
Ответ на: комментарий от geekless

У тебя какие-то проблемы с терминологией.

Можешь подсказать книжку в которой всё хорошо с этой терминологией? Хочется ознакомиться.

Компилятор — это средство для перевода алгоритма из одной знаковой системы в другую.

Хорошо, и в библиотеке v8 есть функция которая занимается переводом JS кода в машинный код.

А что такое интерпретатор? Внезапно — это исполнитель.

И есть функция которая этот скомпилированный код запускает («исполнителем» является процессор, выполнение происходит в рамках рантайма v8, да).

То же самое можно сказать про JVM и SBCL — там есть функции реализующие компилятор и функции запускающее скомпилированный и размещённый в памяти машинный код. Я просто боюсь, как бы они, внезапно, интерпретаторами не оказались :)

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

Можешь подсказать книжку в которой всё хорошо с этой терминологией? Хочется ознакомиться.

Ту самую, что неоднократно в треде упоминалась. Там всё есть.

И есть функция которая этот скомпилированный код запускает («исполнителем» является процессор, выполнение происходит в рамках рантайма v8, да).

Исполнителем является исполнитель. Что бы ты себе не придумывал. Процессор является исполнителем своей системы команд. А исполнителем JS является система их железки, движка v8 и еще кучи промежуточного софта между ними. Чем ты пытаешься живого человека распиливать и задаваться «философскими» вопросами а ля «а вот у человека есть печень, значит человек — это печень?» , мне не совсем понятно.

То же самое можно сказать про JVM и SBCL — там есть функции реализующие компилятор и функции запускающее скомпилированный и размещённый в памяти машинный код. Я просто боюсь, как бы они, внезапно, интерпретаторами не оказались :)

«Виртуальная машина Java интерпретирует и исполняет байт-код Java» (c) википедия

Вот уж внезапно так внезапно.

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

компиляторами из машинного кода в C

/0, как говорится :)

Термы - это элементы некой формальной грамматики.

Неа, грамматика это не множество чтобы иметь элементы. Язык, да, множество, его элементы - термы языка. А (порождающая) грамматика это любой финитно заданый способ перечисления всех термов.

Программа - это записанный при помощи знаковой системы алгоритм. Язык - эта самая система. Исполняется исполнителем.

Те же термы. А вот на язык накладываются ограничения / требуются дополнительные построения. Ну я пример привёл как можно смотреть на язык как на тип, там то же самое, только в рамках известной метатеории, а не на алхимическом наречии.

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

«Виртуальная машина Java интерпретирует и исполняет байт-код Java» (c) википедия

«The JVM runtime executes .class or .jar files, emulating the JVM instruction set by interpreting it, or using a just-in-time compiler (JIT) such as Oracle's HotSpot. JIT compiling, not interpreting, is used in most JVMs today to achieve greater speed. There are also ahead-of-time compilers that enable developers to precompile class files into native code for particular platforms.» (c) same shit.

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

С бега, подтягиваний, отжиманий и прочих упражнений для общей физической подготовки. Судя по поставновке вопроса, ты поступил туда, где не можешь и не хочешь учиться. Зачем мучать себя и, упаси хосспати, госбюджет?

Я в отличной физ. подготовке, учиться хочется, просто препод нормально информацию преподнести не может, а учусь я на платном, т.к. 1 бала на бесплатное не хватило (5 бесплатных, я был 6; 18 человек учится), вот и подумай как я учусь!

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

Тупой? ТСу как минимум компилятор нужен, если не суперкомпилятор. А ты тут с щилдтом убогим.

Какой к черту суперкомпилятор. ТС курсовой нужен, а те теории.

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

по задаче инструмент время ограничено и цено и т.п.

т.е некотором необходима книга_дракона

многим другим полезна книга_дракона

прежде чем решать интегралы полезно уметь записывать формулы символьно и не ограничиватся словами (Евклиду было достаточно и что сразу Началу курить?)

и что за поклонение перед учебными курсами ? если уж Ахо Ульмана советовать так давай «Теория синтаксического анализа перевода и компиляции» оно полнее.

поэтому Креншоу - Пишем компилятор поэтому Вирт Построение комприляторов

и в 1ом и в 2ом есть достаточная ТС реализация с обьяснением интерпретатора

qulinxao ★★☆
()

вот и подумай как я учусь!

nobody cares

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

Disassembler, decompiler - тоже компиляторы?

ну конечно же. Это ведь одна и та же программа, только на разных языках/VM. И IDA тоже, хотя «полуавтоматический» — часть работы выполняется ручками.

Если оптимизатор строит программу, семантически эквивалентную исходной до оптимизации, но другую — то декомпилятор делает этот проход в обратную сторону. И тут возникают неоднозначности, но нас они не волнуют — потому что все эти виртуальные машины/языки/программы эквивалентны в смысле, понимаемом задаваемой VM/языком/программой.

anonymous
()

Взять коды FreeBasic'а и переписать их на плюсы.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Deleted

Но покажи мне такие дизассемблеры и декомпиляторы, которые уже в 100% случаев дают код, который после сборки ведет себя так же, как и изначальный дизассемблированный/декомпилированный бинарник

лолшто?
1. дизассемблируй а потом ассемблируй заново. В чём разница?
2. декомпилируй а потом скомпилируй заново. Что, сложно одинаковый рантайм исходной программе соблюсти?

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

Disassembler, decompiler - тоже компиляторы?

Результат не является эквивалентной программой.

лолшто?

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

1) покажи на своем примере. совершенный дизассемблер пока еще не изобретен, и даже IDA в большинстве случаев дает код, который после пересборки не работает. Причины: 1) дизассемблер не всегда понимает, где код, а где - данные, 2) дизассемблер почти никогда не понимает, где смещение, а где - просто число, 3) ну и другие ошибки в том же роде...

2) покажи совершенный декомпилятор. все, что я видел - либо парсит коды всяких высокоуровневых виртуальных машин (Java и прочие), либо почти что не работает вообще.

Deleted
()
Ответ на: комментарий от quasimoto

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

но если мы эту программу на Си соберём хотя бы двумя разными компиляторами, мы получим два разных бинарника, эквивалентых (тот же смысл), но не идентичных (разные рантаймы, опции оптимизации и т.п.) исходному.

Поэтому декомпилированная программа — эта программа для виртуальной машины, задающей конкретный компилятор, опции сборки и т.п.

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

Если я буду исполнять JS при помощи ручки и бумажки, я буду являться точно таким же исполнителем как тот, что входит в состав фирефокса. И никакого «рантайма» у меня нет.

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

anonymous
()

Студент (лат.) — самообучающийся

april
()
Ответ на: комментарий от Deleted

и даже IDA в большинстве случаев дает код, который после пересборки не работает. Причины:

а ничего, что IDA — интерактивный дизассемблер и при правильной прокладке между сиденьем всё работает? просто декомпилятор — это человеко-машинная система: машина колбасит, человек понимает

покажи совершенный декомпилятор

IDA + anonymous + куча разных ad hoc языков

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.