Важная информация

User Tag List

Страница 1 из 4 1234 ПоследняяПоследняя
Показано с 1 по 10 из 33

Тема: Построение компилятора

  1. #1
    Veteran
    Регистрация
    29.12.2010
    Адрес
    Москва
    Сообщений
    1,858
    Спасибо Благодарностей отдано 
    131
    Спасибо Благодарностей получено 
    104
    Поблагодарили
    62 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию Построение компилятора

    Решил продолжить копания в теме построения собственного компилятора для z80, скорее всего, на основе Паскаля. С лексическим и синтаксическим анализом вроде разобрался, написал что надо в Coco/R.
    Сейчас пытаюсь понять принцип построения синтаксического дерева. Статья Vitamina про распознавание арифметических выражений понравилась, и там же написано вот что:
    Таким образом, т.е.согла-
    сно алгоритму Дейкстры, можно перевести в
    ОПЗ не только арифметическое выражение, но
    и программу на ЯВУ (Языке Высокого Уров-
    ня).При этом нужно определить дополнитель-
    ные классы лексем: описание и вызов функ-
    ций, описание и адресация массивов, услов-
    ные и безусловные переходы. В результате
    получится описание на языке низкоуровневых
    конструкций, как нельзя лучше приспособ-
    ленных к дальнейшей трансляции в машинный
    код. Подробную информацию можно получить в
    литературе по данной теме.
    Описание алгоритма сортировочной станции (Дейкстры) нашел, но вот никак фантазии не хватает, что делать в случае встречи операторов типа IF-ELSE, WHILE, GOTO, индексы массива... (BEGIN-END интерпретировать как скобки можно, наверно). Нигде не нашел конкретного описания для них.
    Помогите, чем можете

  2. #1
    С любовью к вам, Yandex.Direct
    Размещение рекламы на форуме способствует его дальнейшему развитию

  3. #2
    ZEK
    Гость

    По умолчанию

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

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

  4. #3
    Guru Аватар для jerri
    Регистрация
    01.03.2005
    Адрес
    Samara
    Сообщений
    4,751
    Спасибо Благодарностей отдано 
    256
    Спасибо Благодарностей получено 
    266
    Поблагодарили
    200 сообщений
    Mentioned
    12 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Andrew771, вообще-то компилятор учат делать в институте на 3ем или 4ом курсе.
    Кстати зачем оно тебе?
    С уважением,
    Jerri / Red Triangle.

  5. #4
    Vitamin C++ Аватар для Vitamin
    Регистрация
    14.01.2005
    Адрес
    Таганрог, Россия
    Сообщений
    4,254
    Спасибо Благодарностей отдано 
    9
    Спасибо Благодарностей получено 
    80
    Поблагодарили
    34 сообщений
    Mentioned
    7 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    ЕМНИП, перевод конструкций примерно следующий:
    Код:
    if (condition)
    then
      positive
    else
      negative
    endif
    переводится в
    Код:
    call check_condition ; C if succeed
    jp nc,failed
    <positive>
    jp endif
    failed:
    <negative>
    endif:
    Код:
    while (condition)
      body;
    переводится в
    Код:
    while_loop:
    call check_condition
    jp nc,while_end
    <body>
    jp while_loop
    while_end:
    GOTO переводится в JP, очевидно же.
    BEGIN/END действительно могут интерпретироваться как скобки, но исключительно на своем уровне интерпретации (т.е. блочном).

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

  6. #5
    Banned
    Регистрация
    25.01.2005
    Адрес
    Miass, Chelyabinsk region
    Сообщений
    4,094
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    2
    Поблагодарили
    2 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

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

  7. #6
    ZEK
    Гость

    По умолчанию

    1,2 шаг coco/r делает
    на выхлопе парсера иногда проще иметь промежуточный либо стековый либо 3х операндный код, а его уже в ассемблер или машкод переводить, правда если сразу в машкод, придется с адресами переходов самому возиться, можно комбинировать, арифметику стековым промежуточным кодом, будет гораздо проще и автоматом ОПЗ получается

  8. #7
    Veteran
    Регистрация
    29.12.2010
    Адрес
    Москва
    Сообщений
    1,858
    Спасибо Благодарностей отдано 
    131
    Спасибо Благодарностей получено 
    104
    Поблагодарили
    62 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от ZEK Посмотреть сообщение
    ast зачем? можно по мере разбора генерить код, ast нужен для высокоуровневых оптимизаций, типа вынос за цикл итд, LL1 тем и удобен что все что на вход попадает практически сразу можно на выхлоп кодогенератору отдавать
    Дерево вот именно для последующих оптимизаций и хочу получить. Пробовал напрямую код генерить, без ОПЗ сложно.

    Цитата Сообщение от ZEK Посмотреть сообщение
    Разбор арифметических выражений с приоритетами итд, делается просто вкладыванием лексем друг в друга в нужном порядке, на верхнем уровне самые низкоприоритетные, чем глубже тем приоритет выше
    а для операторов ЯВУ также можно расставить приоритет?

    Цитата Сообщение от jerri Посмотреть сообщение
    Andrew771, вообще-то компилятор учат делать в институте на 3ем или 4ом курсе.
    Кстати зачем оно тебе?
    Угу. Только я по специальности не программист, так что у нас не было. Хочу кросс-компилятор Паскаля сделать для Спектрума. Причем со встроенными некоторыми библиотечными функциями (вывод спрайтов, текста и т.д.)

    Цитата Сообщение от Vitamin Посмотреть сообщение
    перевод конструкций примерно следующий
    да, это не сложно. Но приоритет и последовательность операторов вот только из дерева можно получить (?).

    Цитата Сообщение от Vitamin Посмотреть сообщение
    потом синтаксический анализ (подготовка внутреннего кода в форму ОПЗ, например)
    вот этот этап вызывает у меня затруднения.

    ---------- Post added at 17:21 ---------- Previous post was at 17:19 ----------

    Цитата Сообщение от ZEK Посмотреть сообщение
    на выхлопе парсера иногда проще иметь промежуточный либо стековый либо 3х операндный код, а его уже в ассемблер или машкод переводить
    ОПЗ, как я понимаю, стековый код?

  9. #8
    ZEK
    Гость

    По умолчанию

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


    Цитата Сообщение от Andrew771 Посмотреть сообщение
    Пробовал напрямую код генерить, без ОПЗ сложно.
    Генери промежуточный код, тут тоже какие то оптимизации можно делать, замены по шаблонам

    Цитата Сообщение от Andrew771 Посмотреть сообщение
    а для операторов ЯВУ также можно расставить приоритет?
    зачем? операторы последовательно выполняются

    Цитата Сообщение от Andrew771 Посмотреть сообщение
    ОПЗ, как я понимаю, стековый код?
    ну да, парсер к примеру из кода

    "var1 * 5 + var2" может делать что то такое

    ld var1 // загружает переменную на вершиу стека
    const 5 // ложит на вершину стека константу
    mul // берет 2 значения с верхушки стека, перемножает и ложит результат обратно
    ld var2
    add

    это на промежуточном коде, его потом в ассемблер перевести не проблема

    приортитеты можешь не париться, надо просто правильно нарисовать правила для coco/r, он сам разберет по приоритетам сырок

    ---------- Post added at 16:51 ---------- Previous post was at 16:40 ----------

    Вот пример разбора сишного сырка по сишным приоритетам

    Код:
    Expr       = AssignExpr {','  AssignExpr}.
    AssignExpr = CondExpr [AssignOp AssignExpr]. // relaxed
    CondExpr   = LogOrExpr ['?' Expr ':' CondExpr].
    LogOrExpr  = LogAndExpr {"||" LogAndExpr}.
    LogAndExpr = OrExpr {"&&" OrExpr}.
    OrExpr     = XorExpr {'|' XorExpr}.
    XorExpr    = AndExpr {'^' AndExpr}.
    AndExpr    = EqlExpr {'&' EqlExpr}.
    EqlExpr    = RelExpr {("==" | "!=") RelExpr}.
    RelExpr    = ShiftExpr {('<' | '>' | "<=" | ">=") ShiftExpr}.
    ShiftExpr  = AddExpr {("<<" | ">>") AddExpr}.
    AddExpr    = MultExpr {('+' | '-') MultExpr}.
    MultExpr   = CastExpr {('*' | '/' | '%') CastExpr}.
    CastExpr   = IF(IsType1()) '(' TypeName ')' CastExpr
               | UnaryExpr.
    
    UnaryExpr =
      {"++" | "--"}
      ( PostfixExpr
      | UnaryOp CastExpr
      | "sizeof"  (IF(IsType1()) '(' TypeName ')' | UnaryExpr)
      ).
    
    PostfixExpr =
      Primary
      { '[' Expr ']' 
      | '.'  ident
      | "->" ident
      | '(' [ArgExprList] ')' 
      | "++" 
      | "--"
      }.
    Приоритет формируется порядком вложенности одних лексем в другие
    Последний раз редактировалось ZEK; 26.11.2013 в 17:43.

  10. #9
    Banned
    Регистрация
    25.01.2005
    Адрес
    Miass, Chelyabinsk region
    Сообщений
    4,094
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    2
    Поблагодарили
    2 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Andrew771 Посмотреть сообщение
    Хочу кросс-компилятор Паскаля сделать для Спектрума.
    самый быстрый путь в лоб - конвертить его в си, потом sdcc или iar

  11. #10
    Sinclair User Аватар для Eltaron
    Регистрация
    16.01.2005
    Адрес
    Ekaterinburg
    Сообщений
    2,045
    Записей в дневнике
    7
    Спасибо Благодарностей отдано 
    143
    Спасибо Благодарностей получено 
    463
    Поблагодарили
    326 сообщений
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от psb Посмотреть сообщение
    самый быстрый путь в лоб - конвертить его в си, потом sdcc или iar
    Еще быстрее - взять готовый паскаль под CP/M, и запускать под CP/M-эмулятором. Высокоуровневые (BDOS) эмуляторы прозрачно работают с существующей файловой системой PC.
    Граф Дракула наш кумир, патамушта он вомпир!
    VKINK 9 : BORDER NOT PI

Страница 1 из 4 1234 ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. Interference:построение таблицы
    от goblinish в разделе Программирование
    Ответов: 6
    Последнее: 17.11.2012, 13:43
  2. Кодогенерация SDCC: пожелания об улучшении компилятора
    от Oleg N. Cher в разделе Программирование
    Ответов: 99
    Последнее: 10.11.2012, 16:05
  3. 3D-View - построение 3D перспективы
    от Andrew771 в разделе Софт
    Ответов: 4
    Последнее: 02.11.2012, 11:46
  4. Конструктор для компилятора с Си
    от Raydac в разделе Программирование
    Ответов: 0
    Последнее: 21.12.2009, 23:14

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •