LINUX.ORG.RU

конвертер программы с языка Си на язык Паскаль


0

2

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


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

и кровать в общаге сломалась (закон Мерфи, да), ножку подперли драгонбуком. ЧСХ, конструкция выдержала!)

[история успеха]

anonymous
()

ещё можно взять ANTLR

Надо написать конвертер программы с языка Си на язык Паскаль. НА С++

про классический парсер типа lex/bison, тут уже сказали. Замечу только, что на ANTLR подобный парсер пишется проще и технологичнее:
1) ANTLR автоматизирует построение AST — обычная грамматика может иметь options {output=AST;}, и тогда в такой грамматике задаются правила, по которым из потока лексем конструируется AST, например 'int' ID ';' -> ^(DECL ID INT) означает что строится поддерево, у которого ^ будет новым корнем, или 'int' ID !';' (ЕМНИП) — построить поддерево из токенов, проигнорировав ;. Это называется tree grammar, грамматика для описания AST. Аналогичным образом tree grammar может задавать правила (rewriting rules), по которым из одного дерева строится другое, что полезно например для семантического анализа.
Также, грамматика в качестве результата может иметь шаблон (StringTemplate), что полезно для генерации pretty printer-ов, то есть кодогенератора, распечатывает AST в синтаксисе целевого языка. Это простой язык шаблонов с переменными, if/then/else, которые к тому же можно строить из других шаблонов.
2) есть удобные инструменты: ANTLRWorks — GUI для разработки грамматики и отладчик
3) есть gUnit — юниттестирование построенного парсера, задавая тесты в виде грамматик
4) есть уже готовые грамматики под С,С++ и т.п.
5) Переносимость. Сам ANTLR — это библиотека на Java, распространяется в виде .jar архива. Но парсер, который строится ANTLR-ом может генериться на любом языке (сам язык в исходниках ANTLR задаётся через StringTempate). Есть уже готовые 16 языков, см. http://www.antlr.org/wiki/display/ANTLR3/Code Generation Targets — разной степени свежести, но C/C++/C# поддерживаются в основном дереве аналогично Java, и обновляются своевременно. С++: http://www.antlr.org/wiki/pages/viewpage.action?pageId=29130826
6) Примеры и книги, документация. Лучше читать по книжкам, http://www.pragprog.com/titles/tpantlr/the-definitive-antlr-reference http://pragprog.com/titles/tpdsl/language-design-patterns , вторая более новая и ориентирована на разработку DSL на примерах. Можно скачать исходники к книжке. Ещё есть архив с примерами. Ещё есть исходники Mantra — пример реализации языка от автора ANTLR.
В принципе, примеров достаточно для реализации простого парсера. В примерах examples-v3.tar.gz в java/cminus есть почти твой случай — пример конвертации из языка SimpleC (упрощённый С) в Java/Python/Java bytecode (на StringTemplate, то есть можно прицепить ещё хоть 10 языков, всякие паскали и обероны).
7) Java/C++ фанаты на этом идут пилить реализацию семантического анализатора для своего парсера. А лисп-панки могут сделать проще:
а) AST.toStringTree() распечатает AST в виде S-выражений (правда, форматирование некрасивое). Остаётся взять и наколбасить макросов, которые токены узлов AST раскроют в кошерный лисп или схему. А уже его компилировать обычным лисп компилятором, в нативный код или через C. Для схемы с гигиеничными макросами в целом код получается проще и чище, но для CL тоже не очень сложно.
б) Можно взять Clojure (это такая Ява с синтаксисом лиспа), и подёргать из REPL за Java-методы сам ANTLR.

anonymous
()
Ответ на: ещё можно взять ANTLR от anonymous

за ANTLR: 1) оно в целом технологичнее. Из готовых компонентов (готовой грамматики C/C++) и готовой остнастки для юнит-тестирования грамматик составляются компоненты парсера. Плюс, берём к примеру maven, говорим ему «создай проект по архетипу ANTLR» — и у нас готовая заготовка ANTLR-проекта, ничего не надо качать и настраивать вручную, само всё скачает и на блюдечке принесёт. В случае С++ тут надо будет немного повозиться вручную с target C++, и сборкой С++ проекта, ну да тоже особо не сложно. 2) больше гибкости и возможностей. Например, семантические и синтаксические предикаты в грамматиках, rewrite rules, StringTemplate.

против ANTLR: 1) да, освоить не очень просто. Нужно обложиться примерами, лучше — готовых opensource компиляторов на ANTLR, хуже — учебными примерами с сайта самого ANTLR, а ещё лучше — книжками, и вдумчиво читать и пробовать. 2) код парсера на языке Code Generation Target (Java/C++/C#/..) всё-таки придётся писать, и чем сложнее исходный язык (грамматика), тем сложнее получается код, чтобы учесть все семантические тонкости. 3) ANTLR автоматизирует много вещей, так что если нужно разобраться, как эти вещи работают изнутри — лучше написать самому. Самые упорные берут flex/bison/PEG/свой личный парсер по вкусу, и делают деревья вручную. Зато ты с предельной ясностью будешь понимать что такое AST, каким типом данных должны быть его узлы, как они должны быть связаны, какие проходы по дереву/преобразования тебе нужны — всё это нужно будет делать вручную, и в голове лучше отложится, как эти вещи работают.

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

И до тайпчека мы просто _не можем_ получить синтаксическое дерево. В отличии от паскаля и других КС-языков. Раз мы не можем получить АСТ до тайпчека, то алгоритм тайпчека - часть АСТ. Точнее, не весь алгоритм тайпчека, а только уче ттакого какие типы мы имеем на данный момент.

ну то есть: 1) граматика паскакаля, модулы,оберона и в некоторой степени даже Go была специально продумана таким образом, чтобы уже на этапе парсинга не возникало неоднозначностей в семантике, и парсить можно было бы каким-то простым LALR. В итоге, построенное синтаксическое дерево — уже и семантическое. 2) для C и особенно С++ есть много хитрых примеров неоднозначностей. например, type1 func(1); // С++: это что, вызов func через указатель, описание переменной с конструктором, приведение 1 к типу func и т.п. в общем случае a b(c) ; ничего невозможно сказать что это, не зная типов a,b,c, и символьной таблицы, что тут переменная, что функция, что описание типа. То есть, AST в случае С++ — это не совсем семантическое дерево, а его заготовка, по которой нужно делать проход визитором например (или семантическими предикатами), и подтвердить семантическую корректность. Для Паскаля, кстати, можно например написать такую грамматику, в которой в примере 1) var a: real; begin sin(a); end. 2) var a: string; begin sin(a); end. некорректной программы во втором случае не будет построено некорректного дерева уже на этапе парсинга. То есть, добавляем в грамматику в функции sin, добавляем в аргументы sin NumberLiteral | VarNumber — получаем «предопределённую» на уровне грамматики функцию sin, которой string нельзя передать в принципе. Хотя конечно с символьной таблицей получается проще.

Конечно же, никакого эффективного парсинга тогда ждать не приходится - и это не единственная проблема.

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

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

А зачем нам писать грамматику, с точки зрения которой вторая строка не верна, если эта строка по факту верна?

что значит «по факту верна»? с точки зрения синтаксиса, конкретного синтаксиса — «по факту верна». с точки зрения семантики (а АСТ, как мы помним — это дерево с абстрактным, достаточно общим для семантической корректности, синтаксисом) — не верна. выходит, нужно или 2 и более деревьев, где строка более верна или менее верна на каждом новом уровне. либо, задавать правила вывода таких деревьев каким-то общим способом. то что такой общий способ есть, показывает подход в том же ANTLR к tree grammars: лексер стоит поток токенов, лексем из потока символов, парсер синтаксический строит дерево вывода в конкретном синтаксисе из потока лексем, парсер семантический строит синтаксическое дерево (оно же, AST если абстрактный синтаксис=семантика), оптимизатор в миддлэнде строит более другое но эквивалентное семантически дерево, кодогенератор строит более другое, но эквивалентное во всех предыдущих смыслах дерево — структурный по сути документ, который описывает бинарный код с секциями (узел дерева = секция), которое почему-то строится не таким же способом, а уже опять как поток не очень структурированного текста или бинаря: ассемблером в объектник, линкером статическим в бинарник, линкером динамическим и ядром в образ процесса в момент запуска бинарника с диска.

Напрашивается вопрос, а нафига одинаковые по сути задачи решаются столь разными способами. На эту тему в парсеростроении тоже есть прогресс, например, парсер Template в GoLang от Пайка и Кернигана — через каналы синхронизируются процессы с деревьями разных уровней, и ВНЕЗАПНО, выходит, что и парсер и лексер описываются единообразно; или PEG , Tree PEG или ОMeta, когда выясняется что лексер не нужен, а нужен парсер в объекты и парсер таких парсеров другим парсером. В компиляторостроении пока не всё так гладко, хотя определённый прогресс есть, см. например компилятор com-example от Ian Piumarta — там на основе PEG cделан лексер/парсер/кодогенератор (АСТ строится в виде S-выражений специального вида, которое просто разворачивается во что нужно), компилятор языка ooc на основе PEG или nya/chlion на основе tree PEG. И даже в некоторой степени Red/System, в котором реализован однопроходной кодогенератор в нативный код, то есть линкер — на языке вроде РЕБОЛа. И зачем нужна в таком контексте традиционная организация компиляторного тулчейна? Ну, оптимизацию по скорости ещё допустим можно понять. А в остальном — не очень внятный дизайн всего традиционного компиляторного тулчейна целиком. Хотя этот новый дизайн золотыми молотками попахивает.

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

ну то есть: 1) граматика паскакаля, модулы,оберона и в некоторой степени даже Go была специально продумана таким образом, чтобы уже на этапе парсинга не возникало неоднозначностей в семантике, и парсить можно было бы каким-то простым LALR.

Ну да. Она специально была сделана КС-грамматикой.

anonymous
()

Топикстартеру советую начать с примеров, которыми собираешься демонстрировать работоспособность транслятора. Слева пишем исходный код на Си, справа целевой код на паскакале. И тщательно обрабатываем случаи неоднозначностей на Си — как такой код должен транслироваться, и почему одна и та же строка в разном контексте на исходном языке должна транслироваться в сильно разное на целевом языке. Если выберешь для примеров какое-то упрощённое, но достаточно полезное подмножество языка Си, можешь сильно облегчить себе работу, хотя спортивный интерес уже пропадёт.
Затем, нужно иметь общее понятие, как работает транслятор. Книжка по ANTLR (The definitive guide) говорит нам, что есть 2 типа трансляторов — rewriters и pretty printers. В первом случае можно переписывать входной текст на уровне текста, во тором парсер строит структуру, которая заменяется другой структурой и эта структура уже распечатывается.
В случае ANTLR — на эти части транслятора легко ложится готовые компоненты ANTLR: лексер/обычная грамматика для построения токенов, парсер/«деревянная грамматика» для построения или переписывания дерева, StringTemplate для вывода структурированного текста распечатыванием этого дерева.
В случае если делать вручную — замени готовые компоненты на свои. Ну то есть, пишешь свой recursive descent parser ручками, ручками делаешь АСТ и ручками его распечатываешь(избежав по возможности копирования строк туда-сюда алгоритмом маляра Шлемиля).

Если времени много есть, а понимания процесса нет — полезно сделать одно и то же разными способами и сравнить ощущения.

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

(а АСТ, как мы помним — это дерево с абстрактным, достаточно общим для семантической корректности, синтаксисом)

Ну да, только понятие «достаточно общим для семантической корректности, синтаксисом» - это понятие нечеткое и является, в реальности, продуктом некоего соглашения. Никто не мешает, повторюсь, взять регулярную грамматику и построить дерево как token(x, token(y, ...))) и потом кричать, что ЯП регулярен, но нахера такой АСТ нужен? Если же идти в облатсь корректности то можно и вовсе потребовать от АСТ, чтобы он строился только в том случае, если программа гарантированно корректна (то есть в принципе не может упасть), проверка чего будет алгоритмически неразрешима. Существуют просто некоторые эффективные алгоритмы парсинга, методы их описания и т.п. - и удобно отделить этап, на котором применимы эти алгоритмы, от любого другого этапа. То есть, с одной стороны, нам бы хотелось, чтобы грамматика более точно описывала семантику, с другой - была КС (есть и еще один критерий - удобство с точки зрения рпограммиста, который будет писать на этом ЯП, но мы его поустим) для применение тех самых развитых подходов и алгоритмов. Вот в паскале мы используя КС-грамматику может всегда отделить имя типа о тимени переменной. В сишке - не можем. Варианта два - отказываться от КС-грамматики, либо вместо двух токенов TypeName IdName оставить один - ну в этом случае еще все могло бы быть неплохо, но есть ведь и другие неоднозначности. Котоыре при сведении грамматики к КС дадут то самое дерево навроде token(x, token(y, ...)).

или PEG , Tree PEG или ОMeta

Не понял, и как ты собрался на пеге делать, например, тайп инференс? Суть то в том как раз что на каждом этапе нам требуются различные по выразительности средства решения. Для лексера достаточно конечного автомата, для парсера - стекового, а дальше нам уже нужна вся машина тьюринга. И с точки зрения дизайна и абстракции нам на каждом уровне удобно себя ограничить максимально возможным способом.

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

Никто не мешает, повторюсь, взять регулярную грамматику и построить дерево как token(x, token(y, ...))) и потом кричать, что ЯП регулярен, но нахера такой АСТ нужен?

ну то есть, изобрести Skeleton syntax tree? Там есть макросы в языке с обычным синтаксисом (хотя грамматика КС специально для парсинга LALR). Текст находится внутри какого-то блока, эти блоки — узлы дерева скелетного синтаксиса. Структура блоков одинаковая, внутри блока — различия.

http://people.csail.mit.edu/jrb/jse/java-macros_files/frame.htm
http://people.csail.mit.edu/jrb/jse/jse.pdf

D-expressions in DylanLanguage. There's a paper on this by JonathanBachrach?, and it's the implementation strategy in FunctionalDeveloper?. This is a way to tap into the AbstractSyntaxTree of parsed Dylan code fragments, except it actually works at a slightly higher level (the skeleton syntax tree). It then provides a GenericFunction interface to manipulate code fragments. Basically all of Dylan syntax is represented as D-expressions in FunctionalDeveloper?, which is an elegant approach that unfortunately leads to impenetrable error messages when using that IDE. DSLs like the Dylan User Interface Manager are done using Dylan macro

Варианта два - отказываться от КС-грамматики, либо вместо двух токенов TypeName IdName оставить один - ну в этом случае еще все могло бы быть неплохо, но есть ведь и другие неоднозначности. Котоыре при сведении грамматики к КС дадут то самое дерево навроде token(x, token(y, ...))

собсно и Skeleton syntax tree, и синтаксические объекты в схеме это и есть примерно такое дерево. В Dylan в D-выражениях http://people.csail.mit.edu/jrb/Projects/dexprs.pdf работают макросы, хотя LALR грамматика.

Не понял, и как ты собрался на пеге делать, например, тайп инференс?

Я про эту работу (com-example): http://www.vpri.org/pdf/tr2010003_PEG.pdf

Вот есть например OMeta http://www.moserware.com/2008/06/ometa-who-what-when-where-why.html PDF: http://www.cs.ucla.edu/~awarth/papers/dls07.pdf

Это не PEG, это расширение PEG-а, в котором на выходе — объекты. Исходно был в META объектом — шаблон кода на лиспе, в который подставлялись распарсенные из грамматики токены. В OMeta# , который на C# (ещё на C# есть похожий IronMeta) в лямбды подставляются типизированные значения. То есть, в шаблон с типизированным уже кодом подставляются распарсенные токены уже известного на уровне этого шаблона типа.

  • Если в OMeta# исходный язык — OMeta, целевой — C#, то в OMeta просто — и исходный, и целевой OMeta.

  • А вот с типом тут просто в простых случаях, да. То есть, в сложных нужно придумать какой-то typetuple, в виде пар (тип,токен) — можно транслировать код в код с какой-то рантайм подпоркой, раз, и обеспечить, чтобы рантайм-подпорка была не нужна, два. То есть, чтобы все такие пары по всем случаям входного языка можно было бы вычислить на этапе компиляции.

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

    Ещё OMeta в плане производительности скажем, не блещет — в рассылке были примеры неигрушечной грамматики — Delphi на OMeta, кажется автор забил и перешёл на PEG в Rats! — он приводил цифры со сравнениями производительности парсеров (легкость разработки самого парсера однако тоже надо бы учитывать).
    Вот ограничения с точки зрения производительности и интересны.
    То есть: не нужна машина тьюринга полноценная, нужно какое-то подмножество типа шаблонов (шаблоны С++ скорее всего не годятся, в отличие от шаблонов в D).
anonymous
()
Ответ на: комментарий от anonymous

Ну да, только понятие «достаточно общим для семантической корректности, синтаксисом» - это понятие нечеткое и является, в реальности, продуктом некоего соглашения.

а что мешает это соглашение описать чётко, в виде кода с (DbC)контрактным программированием?

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

Ребят вы просто жжоте!!!

Ss
() автор топика
Ответ на: ещё можно взять ANTLR от anonymous

Чесно говоря я уже запутался что и как мне надо делать.

Если допустим делать как тут http://gnuu.org/2009/09/18/writing-your-own-toy-compiler/ Не очень понятно как ее собрать, как сделать Семантический Анализ с Bison, дерево и далее.. Хотя в голове уже сложилось общее понятие. Сейчас задача состоит в том что бы быстрей написать несложный компилятор. Так как я не очень знаю толк в этом деле,мне сразу этот поток инфо не очень усваевается в голове.

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

То есть, добавляем в грамматику в функции sin, добавляем в аргументы sin NumberLiteral | VarNumber — получаем «предопределённую» на уровне грамматики функцию sin, которой string нельзя передать в принципе. Хотя конечно с символьной таблицей получается проще.

sin-то мы предопределили. Я даже хотел написать, что тип sin известен при разборе, забыл. Но осталась одна мелочишка: у нас имя переменной, идентификатор, определяется программистом, имеет тип и тип этот нельзя узнать из имени переменной. И правила разбора должны быть такими, чтоб разбирать sin(a) или там sin(b) только если a или b были определены ранее и имеют нужный тип и обламываться, встречая sin() от неопределённого ранее идентификатора ну или от идентификатора с неверным типом. На лицо контекстная зависимость. Но некоторые тут сидящие тупорылые анонимусы этого никак не понимают, и орут, что у них паскакаль разбирается КС-правилами.

КС-правилами можно было бы разобрать некий гипотетический паскаль, если бы там были, например, только 3 идентификатора для целых переменных — i, j, k, 3 для float-а вроде f, g, h ну и т.д. Все они должны считаться заданными на этапе разбора. Программисту запретить вводить свои идентификаторы вообще. Вот так, прибив семантику к синтаксису толстыми гвоздями, можно будет разбирать язык КС-правилами.

ram

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

А зачем нам писать грамматику, с точки зрения которой вторая строка не верна, если эта строка по факту верна?

По факту у нас язык паскаль. По факту синус от строки не определён. По факту эта программа не принадлежит ко множеству программ на паскале. По факту она не верна.

Какие у вас такие факты, что по ним программа верна?!!

ram

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

Значит по идее надо изучить что такое AST ? и что еще? Я впервые сталкиваюсь с такой разработкай. ибо на парах лабы только аля решение математических уровнений)

Ещё раз повторю. Начните с теории =) Того же Ахо почитайте.

А к практике потом приступите - после полного понимания того, что прочитаете.

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

определить, что первая программа верна, а вторая — нет

Обе программы синтаксически верны. Type checker может быть вообще undecidable - каким боком он к синтаксическим правилам вывода и синтаксическому разбору? Нам бы сначала (и линейно по сложности) разобрать дерево, а потом уже сколько душе угодно проверять типы, делать AST to AST, и далее по списку (и при ошибке типов гораздо проще о ней сообщить когда есть готовое дерево).

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

он быстрей и*иот!. Тролим мы его) Ну да ладно) Боюсь что на теорию времени уже не очень много). Фиг с ними не сдам.пускай выгоняют

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

Аккуратнее вам так с преподами... вам ещё диплом надо защищать/получать. Чуть больше уважения, это ок?

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

И правила разбора должны быть такими, чтоб разбирать sin(a) или там sin(b) только если a или b были определены ранее и имеют нужный тип и обламываться, встречая sin() от неопределённого ранее идентификатора ну или от идентификатора с неверным типом.

С чего вдруг правила должны быть такими? Это исключительно твои мокрые фантазии.

орут, что у них паскакаль разбирается КС-правилами

То, что паскаль разбирается по КС-грамматике - это _экспериментальный факт_. И ты ори, не ори - ты с _фактом_ ничего не сделаешь.

КС-правилами можно было бы разобрать некий гипотетический паскаль

КС-правилами разбирается вполне реальный паскаль.

Вот так, прибив семантику к синтаксису толстыми гвоздями

Парсер строит синтаксическое дерево. _синтаксическое_. Парсер никак не связан с семантикой. Парсеру _не нужно_ знать типы. Корректность построенного АСТ _не зависит_ от корректности типизации. Это уже область семантики.

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

Какие у вас такие факты, что по ним программа верна?!!

При чем тут верность программы? Речь идет лишь о корректности АСТ, в обои случаях АСТ вполне корректен.

Если ты, блять, хочешь чтобы у тебя парсер допускал только «верные» программы, то сделай по крайней мере так, чтобы он не допускал деления на ноль. Ведь операция деления на ноль не определена? И пусть потом твой парсер разберет мне строку «if GreatFermatsTheoremIsSolved() then 1/0;»

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

В OMeta# , который на C# (ещё на C# есть похожий IronMeta) в лямбды подставляются типизированные значения.

Я нихуя не понял, откуда у тебя взялись типизированные значения? Тебе их боженька дал? Просто дай мне реализацию алгоритма Хиндли-Милнера на своем расширенном PEG.

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

Парсер строит синтаксическое дерево. _синтаксическое_. Парсер никак не связан с семантикой. Парсеру _не нужно_ знать типы. Корректность построенного АСТ _не зависит_ от корректности типизации. Это уже область семантики.

Ты безмозглая необразованная тупорылая шпана. Пойди, читать поучись хотя бы. Я про правила вывода грамматики говорю, а не про парсер. И, идиот, язык и грамматика языка включают в себя и синтаксис, и семантику. А твой сраный парсер разбирает не язык паскаль, а какую-то поебень, которую потом ещё и чекать надо, на то, паскаль это или нет. КС-парсер паскаля от не-паскаля не отличит. ЧТД.

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

При чем тут верность программы? Речь идет лишь о корректности АСТ, в обои случаях АСТ вполне корректен.

Если ты, блять, хочешь чтобы у тебя парсер допускал только «верные» программы, то сделай по крайней мере так, чтобы он не допускал деления на ноль. Ведь операция деления на ноль не определена? И пусть потом твой парсер разберет мне строку «if GreatFermatsTheoremIsSolved() then 1/0;»

Ещё один «гений» не отличает парсеров от правил вывода.

Да, вот нельзя парсером, который реализует КС-грамматику, отличать деление на ноль от деления не на ноль. Это значит, что язык КЗ. :D

В таком случае КЗ сишечки тоже гон. А что нам typedef. Просто будем парсить строки вида «foo a, b, c=0;», а потом каким-нибудь чекером проверять, был ли у нас typedef на foo. Вот и всё ^_^

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

Того же Ахо почитайте.

Учитывая уровень ТСа, тут больше подойдет «Давайте создадим компилятор» Креншоу.

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

Учитывая уровень ТСа - за такие задачи лучше не браться. Я и сам не стал за такое браться... хотя, думаю, возможность взять что-то подобное (но лучше наоборот, из паскаля в сишку, например) была... но учитывая, что у нас был такой курс =) нас всё это объясняли, я знаю, какой это геморрой.

Лучше взять себе что-то попроще... и пополезнее для общества ;) например, доработать любой опенсурс-проект... везде полно багов.

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

Ты какой-то совсем тупой. Иди прочитай уже что-нибудь про формальные грамматики.

Да, вот нельзя парсером, который реализует КС-грамматику, отличать деление на ноль от деления не на ноль. Это значит, что язык КЗ. :D

Нет, этот язык не КЗ. Потому что его и машиной Тьюринга разобрать будет уже нельзя.

В таком случае КЗ сишечки тоже гон.

Нет не гон.

Просто будем парсить строки вида «foo a, b, c=0;», а потом каким-нибудь чекером проверять, был ли у нас typedef на foo. Вот и всё ^_^

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

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

Я про правила вывода грамматики говорю, а не про парсер.

А парсер разбирает грамматику в соответствии с правилами вывода.

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

Грамматика не включает в себя семантику.

А твой сраный парсер разбирает не язык паскаль, а какую-то поебень, которую потом ещё и чекать надо, на то, паскаль это или нет.

То есть парсеров паскаля нет. Потому что чекнуть паскаль - алгоритмически неразрешимая задача (ведь мы никогда не сможем сказать - есть деление на ноль или нет). Ч.Т.Д.

anonymous
()
Ответ на: ещё можно взять ANTLR от anonymous

gUnit это правильное название? Гугл всё выводить каких то исполнителей хип хоп культуры. Времени мало, а дел выше головы. Какой способ лучше? Да и по проще. на Выходе не нужна сильная программа. Я так понимаю что для конвертера нужно: .синтаксический анализ .парсер. .грамматика .ast

Если я прав, значит какими программами можно это всё «сгенерировать».? Если же нет.. тогда с чего сначала начать?

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

Но осталась одна мелочишка: у нас имя переменной, идентификатор, определяется программистом, имеет тип и тип этот нельзя узнать из имени переменной.

да, то есть семантику вида «присваивание неописанной переменной», «некорректное присваивание переменным разных типов» и «вызов функции с корректным типом» — не отследить без таблицы символов в каком-то виде с указанием типа символа

На лицо контекстная зависимость. Но некоторые тут сидящие тупорылые анонимусы этого никак не понимают, и орут, что у них паскакаль разбирается КС-правилами.

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

Вот так, прибив семантику к синтаксису толстыми гвоздями, можно будет разбирать язык КС-правилами.

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

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

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

Грамматика не включает в себя семантику.

Вы чёто путаете. Язык включает в себя и синтаксис, и семантику. Иначе получатся какие-то глосолалии (синтаксис без семантики) или пуськи бятые (семантика без синтаксиса).

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

gUnit это правильное название?

gUnit это http://www.antlr.org/wiki/display/ANTLR3/gUnit - Grammar Unit Testing

http://www.antlr.org/wiki/display/ANTLR3/gUnitEditor - A Swing GUI for gUnit

ещё есть пример на TestNG/JUnit http://www.antlr.org/wiki/display/ANTLR3/Test-Driven Development with ANTLR

Я так понимаю что для конвертера нужно: .синтаксический анализ .парсер. .грамматика .ast

Если я прав, значит какими программами можно это всё «сгенерировать».?

если про ANTLR, всё в одном — можно описать или в одной combined грамматике или в трёх разных: lexer grammar (разбор токенов), parser grammar (парсер), tree grammar (построение AST)

anonymous
()

Тред читал до половины первой страницы, просто скажите, лавсанчег уже набигал с какой-нибудь рекомендацией в стиле «это все должно делаться на лиспе»? По теме двачую модификацию кодогенератора tcc.

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