Автор Тема: [CP][Oberon-07/11]Procedure Type call in expression.  (Прочитано 16417 раз)

Valery Solovey

  • Hero Member
  • *****
  • Сообщений: 509
    • Просмотр профиля
Re: [CP][Oberon-07/11]Procedure Type call in expression.
« Ответ #15 : Январь 13, 2013, 11:05:10 pm »
Добавить родственником давнего предка (следующий оператор текущей процедуры)?
Хотя нет, для этого нужно встретить точку с запятой.

X512

  • Newbie
  • *
  • Сообщений: 45
    • Просмотр профиля
Re: [CP][Oberon-07/11]Procedure Type call in expression.
« Ответ #16 : Январь 13, 2013, 11:07:40 pm »
Ну, КП как минимум абсолютно не портабельный
В каком плане не портабельный? Плохо запускается не разных ОС или сложно написать новый backend?
, да и существенно более сложный (и для реализации и для изучения).
Никто же не заставляет вам его реализовывать. Вы же не пишете для себя компилятор C++ например, не так ли?

Относительно простоты для обучения: я здесь не вижу каких-либо проблем. Базовые конструкции те же, что и в предыдущих оберонах, а ООП для обучения использовать никто не заставляет. Впрочем ООП в Component Pascal очень мощный и простой по сравнению с другими ЯП(С++, Java). ООП это основное преимущество Component Pascal'я перед остальными оберонами.
С другой стороны, я не вижу у Оберона-07/11 преимуществ для микроконтроллеров перед другими языками.
Здесь как раз простота реализации компилятора - очень важное преимущество. Микроконтроллеров много всяких бывает. А полноценных процессора сейчас только три: i386, AMD64 и ARM. Остальные(SPARC, Power PC и т. д.) либо померли, либо имеют специфическое применение.

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: [CP][Oberon-07/11]Procedure Type call in expression.
« Ответ #17 : Январь 13, 2013, 11:14:30 pm »
Стоп-стоп-стоп. Предположим у нас просто парсер, а не компилятор. На выходе он должен тупо выдать AST. Естественно никакого семантического анализатора у него там нет, и тем более тайп-чекера. Внимание вопрос - он тут найдет ошибку? И если нет, то какое дерево он нам построит?
Так или иначе в данном месте исходника выскочит ошибка. Вопрос только: на каком уровне?

Что касается гипотетического многопроходного компилятора... Ну вот прочли мы очередную лексему. Куда её девать? Добавить потомком текущему листу дерева (продолжается текущий операнд выражения)? Добавить родственником недавнего предка (встретилась операция выражения)? Добавить родственником давнего предка (следующий оператор текущей процедуры)?

То есть, по-моему, хоть какая-то контекстная проверка выполняться должна: прочли текущую лексему и изменили список ожидаемых лексем за нею.

Какие родственники, какие лексемы? Ничего не понял.

Все же очень просто: есть токенизатор (ака лексер) распознал лексему - отдал её большому дяде, под названием парсер/синтаксический анализатор. А вот что уже он будет с ней делать, зависит от того какого он типа. Если это примитивный LL(1) в виде рекурсивного спуска, то он будет сравнивать текущую лексему с тем что ожидалось в данном правиле. если ожидалось не то, то перейдет к следующей альтернативе правила. Если это более умная, табличная реализация LL(1)/LL(k), то там все будет похитрее. Есть это LALR, то там будут попытки сверток, то есть совсем иначе. Если это GLR, то еще по другому (будет порождаться потенциально множество альтернативных AST). А если там GLL-алгоритм (который совсем свежий - 2010 год по моему) то там тоже будет нечто свое.

Но при чем тут все эти детали синтаксического анализа применительно к нашей задаче? Ни одна из них в данном случае не требует иметь внесинтаксического контекста (то есть задействовать семантический анализатор) для того, чтобы понять, что AST для данной грамматики по данной входной строке не построить.
Y = λf.(λx.f (x x)) (λx.f (x x))

Valery Solovey

  • Hero Member
  • *****
  • Сообщений: 509
    • Просмотр профиля
Re: [CP][Oberon-07/11]Procedure Type call in expression.
« Ответ #18 : Январь 13, 2013, 11:20:15 pm »
Интересовался этим вопросом, и помню, что в ББ вызов процедур и функций всегда сидел в Designator:
Designator = Qualident {"." ident | "[" ExprList "]" | "^"
| "("Qualident ")" | "(" [ExprList] ")"} [ "$" ].
В секции "(" [ExprList] ")". Так что несколько вызовов подряд соответствуют синтакису.
Просмотрел по диагонали сообщение 07. Похоже, что в нём эквивалентная структура.

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: [CP][Oberon-07/11]Procedure Type call in expression.
« Ответ #19 : Январь 13, 2013, 11:23:14 pm »
Ну, КП как минимум абсолютно не портабельный
В каком плане не портабельный? Плохо запускается не разных ОС или сложно написать новый backend?
Нет. У КП гвоздями прибиты типы к jvm. Как оно будет жить на 64битной машине? А на 16ти битной?

, да и существенно более сложный (и для реализации и для изучения).
Никто же не заставляет вам его реализовывать. Вы же не пишете для себя компилятор C++ например, не так ли?
Так это недостаток (существенный) С++, что там за обозримое время силами 1-2 человек, которые занимаются еще чем-то другим, основным, нельзя нарисовать компилятор. И это одно из основный преимуществ Оберона перед С++.

Впрочем ООП в Component Pascal очень мощный и простой по сравнению с другими ЯП(С++, Java).
Мощный ООП там у ветки Object Oberon'ов (куда входит и КП) относительно основной Оберон-ветки. Но ООП в КП точно не мощнее того что есть в java, и тем более С++.

ООП это основное преимущество Component Pascal'я перед остальными оберонами.
Не факт. У Зоннона и Active-Oberon'a ООП тоже интересное.

Здесь как раз простота реализации компилятора - очень важное преимущество.
Скорее бекенда. + нужно чтобы сам язык был портабельный.

Микроконтроллеров много всяких бывает. А полноценных процессора сейчас только три: i386, AMD64 и ARM. Остальные(SPARC, Power PC и т. д.) либо померли, либо имеют специфическое применение.
Специфическое применение - тоже применение. Грань между микроконтроллером и чем-то "полноценным" очень тонка. Брать язык который только для микроконтроллеров или только для "полноценных" не вижу смысла. C++11 отлично подходит и для того и для другого. Oberon-07/11 более-менее подходит и для того и другого.

Впрочем, мы отклонились от темы.
Y = λf.(λx.f (x x)) (λx.f (x x))

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: [CP][Oberon-07/11]Procedure Type call in expression.
« Ответ #20 : Январь 13, 2013, 11:25:37 pm »
Интересовался этим вопросом, и помню, что в ББ вызов процедур и функций всегда сидел в Designator:
Designator = Qualident {"." ident | "[" ExprList "]" | "^"
| "("Qualident ")" | "(" [ExprList] ")"} [ "$" ].
В секции "(" [ExprList] ")". Так что несколько вызовов подряд соответствуют синтакису.
Просмотрел по диагонали сообщение 07. Похоже, что в нём эквивалентная структура.
И GPCP генерит эквивалентную akorn'овской ошибку.

Короче, я пытался построить AST (руками естественно, парсеры и компиляторы побоку) по Оберон-грамматики для этого случая (GetA()()) и для КП-версии грамматики. У меня не получилось. Если у кого-то получится, прошу поделиться оным AST. Это будет доказательство того, что данная конструкция в данном языке валидна.
Y = λf.(λx.f (x x)) (λx.f (x x))

ddn

  • Jr. Member
  • **
  • Сообщений: 59
    • Просмотр профиля
Re: [CP][Oberon-07/11]Procedure Type call in expression.
« Ответ #21 : Январь 13, 2013, 11:26:43 pm »
Интересовался этим вопросом, и помню, что в ББ вызов процедур и функций всегда сидел в Designator:
Designator = Qualident {"." ident | "[" ExprList "]" | "^"
| "("Qualident ")" | "(" [ExprList] ")"} [ "$" ].
В секции "(" [ExprList] ")". Так что несколько вызовов подряд соответствуют синтакису.
А можно на пальцах, для особо тупых? Разве секция "(" [ExprList] ")" не породит нам вложенные скобочки? Как эта грамматика породит нам GetA()() ?
Не понимаю, что вы имеете ввиду под вложенными скобочками? Если квадратные скобки вложенные в круглые, то квадратные здесь не заключены в кавычки и не войдут в слово языка КП, они суть операторы языка РФБН.
Если вы о последовательно идущих круглых скобках, то не забывайте, что этот вариант альтернативы заключен в фигурные скобки, т.е. в оператор бесконечного повторения.
{... "(" [ExprList] ")"}
А можно на пальцах, для особо тупых? Разве секция "(" [ExprList] ")" не породит нам вложенные скобочки? Как эта грамматика породит нам GetA()() ?
Увы, не знаю как записывать абстрактное синтаксическое дерево.
Должно быть как-то так:
Designator -> Qualident R1 ->
[ident "."] ident R1 -> ident R1 -> GetA R1 ->
GetA "(" [ExprList] ")" R1 -> GetA "(" ")" R1 ->
GetA "(" ")" "(" [ExprList] ")" R1 -> GetA "(" ")" "(" ")" R1 ->
GetA "(" ")" "(" ")" R2 -> GetA "(" ")" "(" ")" [ "$" ] -> GetA "(" ")" "(" ")"

Здесь нетерминалы R1 и R2 это
R1 = {"." ident | "[" ExprList "]" | "^" | "("Qualident ")" | "(" [ExprList] ")"} R2.
R2 = [ "$" ].
« Последнее редактирование: Январь 13, 2013, 11:31:46 pm от ddn »

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: [CP][Oberon-07/11]Procedure Type call in expression.
« Ответ #22 : Январь 13, 2013, 11:33:38 pm »
Интересовался этим вопросом, и помню, что в ББ вызов процедур и функций всегда сидел в Designator:
Designator = Qualident {"." ident | "[" ExprList "]" | "^"
| "("Qualident ")" | "(" [ExprList] ")"} [ "$" ].
В секции "(" [ExprList] ")". Так что несколько вызовов подряд соответствуют синтакису.
А можно на пальцах, для особо тупых? Разве секция "(" [ExprList] ")" не породит нам вложенные скобочки? Как эта грамматика породит нам GetA()() ?
Что вы имеете ввиду под вложенными скобочками? Если квадратные скобки вложенные в круглые, то квадратные здесь не заключены в кавычки и не войдут в слово языка КП, они суть операторы языка РФБН. Если вы о последовательно идущих круглых скобках, то не забывайте, что этот вариант альтернативы заключен в фигурные скобки, т.е. в оператор бесконечного повторения.
{... "(" [ExprList] ")"}
Да, спасибо, это я просмотрел.

Выходит, что в большой вероятностью (нужно еще семантику рассмотреть) в GPCP ошибка.
Y = λf.(λx.f (x x)) (λx.f (x x))

Valery Solovey

  • Hero Member
  • *****
  • Сообщений: 509
    • Просмотр профиля
Re: [CP][Oberon-07/11]Procedure Type call in expression.
« Ответ #23 : Январь 13, 2013, 11:56:24 pm »
Интересовался этим вопросом, и помню, что в ББ вызов процедур и функций всегда сидел в Designator:
Designator = Qualident {"." ident | "[" ExprList "]" | "^"
| "("Qualident ")" | "(" [ExprList] ")"} [ "$" ].
В секции "(" [ExprList] ")". Так что несколько вызовов подряд соответствуют синтакису.
А можно на пальцах, для особо тупых? Разве секция "(" [ExprList] ")" не породит нам вложенные скобочки? Как эта грамматика породит нам GetA()() ?
Вложенных скобочек не будет.
Просмотрел пункт 6.5. сообщения. Там первой строкой идёт:Variables of a procedure type T have a procedure (or NIL) as value.То есть, по сути, излишне сжато, а потому пропускается сознанием. Что, естественно, плохо. Особенно для тех, кто не любит делать шаг, пока досконально не изучит место для шага. С другой стороны, это сообщение а не спецификация как таковая.

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

Теперь, я думаю, понятно, но я на всякий случай объясню. Вот РФБН:factor = number | string | NIL | TRUE | FALSE |
set | designator [ActualParameters] | "(" expression ")" | "~" factor.
designator = qualident {selector}.
Вот вызов:GetA()()Сначала разбирается GetA().
Цитировать
GetA()()
По РФБН - это designator [ActualParameters]Смотрится наличие такой процедуры, иначе программа будет синтаксически некорректной. Она возвращает в качестве значения процедуру. А процедуру можно либо присвоить, либо вызвать (как с ней обойтись зависит от последующих лексем). У нас это так:
Цитировать
GetA()()
А вызов процедуры - это designator [ActualParameters]designator в этом случае - GetA().

X512

  • Newbie
  • *
  • Сообщений: 45
    • Просмотр профиля
Re: [CP][Oberon-07/11]Procedure Type call in expression.
« Ответ #24 : Январь 14, 2013, 12:03:55 am »
Нет. У КП гвоздями прибиты типы к jvm. Как оно будет жить на 64битной машине? А на 16ти битной?
А в чём проблема? В документации чётко определено что BYTE, SHORTINT, INTEGER и LONGINT - это знаковые целые числа с размером 1, 2, 4 и 8 байт соответственно. Следовательно основной целый тип INTEGER будет 4-байтным на любой машине. Насколько мне известно даже 16 битный x86 его поддерживает. Не поддерживаемые типы придётся эмулировать, тут ничего не поделаешь. Без это логика программы может просто сломаться от переполнения.
Если использование 4-ёх байтного INTEGER'а неэффективно, то можно сделать специальный модуль HostCpu и объявить в нём HostCpu.Int наиболее эффективный для данной платформы.

Так это недостаток (существенный) С++, что там за обозримое время силами 1-2 человек, которые занимаются еще чем-то другим, основным, нельзя нарисовать компилятор. И это одно из основный преимуществ Оберона перед С++.

... Но ООП в КП точно не мощнее того что есть в java, и тем более С++.
Спорное утверждение. ООП Component Pascal'я обладает уникальными преимуществами перед ООП других ЯП. Например возможность определять как можно расширять запись и связанные с ней процедуры (так называются методы в оберонах). Засчёт отсутствия множественного наследования в Runtime'е BlackBox'а реализована быстрая и эффективная проверка типов, позволяющая писать шины сообщений и расширяемый код.

ООП это основное преимущество Component Pascal'я перед остальными оберонами.
Не факт. У Зоннона и Active-Oberon'a ООП тоже интересное.
Где можно взять компилятор под Windows без эмуляции ОС? Желательно без .NET . Дизайн их ОС ужасный, немедленно вызывает рвотный рефлекс. И название "Bluebottle" соответствующее. Управление тоже очень неудобное.

Микроконтроллеров много всяких бывает. А полноценных процессора сейчас только три: i386, AMD64 и ARM. Остальные(SPARC, Power PC и т. д.) либо померли, либо имеют специфическое применение.
Грань между микроконтроллером и чем-то "полноценным" очень тонка.
Как раз грань очень чёткая: микроконтроллер - это обычно 8-ми или 16-ти разрядный процессор с интегрированными ОЗУ и ПЗУ небольших объёмов. Код и данные обычно адресуются независимо. Примеры: PIC, AVR.

ARM'ы - это уже полноценные процессоры и на них уже можно использовать все возможности Component Pascal в том числе сборку мусора (она будет быстрой на небольшом объёме памяти).

Брать язык который только для микроконтроллеров или только для "полноценных" не вижу смысла. C++11 отлично подходит и для того и для другого. Oberon-07/11 более-менее подходит и для того и другого.
Никто не заставляет использовать все возможности Component Pascal'я при программировании софта для микроконтроллеров. Понятно, что там не будет сборщика мусора и основными целыми типами будут BYTE и SHORTINT. C++11 также можно использовать при программировании софта для микроконтроллеров в очень небольшом (1%) подмножестве. STL использовать нельзя.

Впрочем, мы отклонились от темы.
Новую тему создать?

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: [CP][Oberon-07/11]Procedure Type call in expression.
« Ответ #25 : Январь 14, 2013, 12:15:55 am »
Интересовался этим вопросом, и помню, что в ББ вызов процедур и функций всегда сидел в Designator:
Designator = Qualident {"." ident | "[" ExprList "]" | "^"
| "("Qualident ")" | "(" [ExprList] ")"} [ "$" ].
В секции "(" [ExprList] ")". Так что несколько вызовов подряд соответствуют синтакису.
А можно на пальцах, для особо тупых? Разве секция "(" [ExprList] ")" не породит нам вложенные скобочки? Как эта грамматика породит нам GetA()() ?
Вложенных скобочек не будет.
Относительно КП, с точки зрения синтаксиса, меня уже ткнули в нужное место грамматики, так что с КП в этом плане вопрос закрыт (но нужно еще пошерстить в плане семантики, маловероятно что там обнаружится что-то запретительное, но тем не менее) .

Просмотрел пункт 6.5. сообщения. Там первой строкой идёт:Variables of a procedure type T have a procedure (or NIL) as value.То есть, по сути, излишне сжато, а потому пропускается сознанием. Что, естественно, плохо. Особенно для тех, кто не любит делать шаг, пока досконально не изучит место для шага. С другой стороны, это сообщение а не спецификация как таковая.

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

Теперь, я думаю, понятно, но я на всякий случай объясню. Вот РФБН:factor = number | string | NIL | TRUE | FALSE |
set | designator [ActualParameters] | "(" expression ")" | "~" factor.
designator = qualident {selector}.
Вот вызов:GetA()()Сначала разбирается GetA().
Цитировать
GetA()()
По РФБН - это designator [ActualParameters]Смотрится наличие такой процедуры, иначе программа будет синтаксически некорректной. Она возвращает в качестве значения процедуру. А процедуру можно либо присвоить, либо вызвать (как с ней обойтись зависит от последующих лексем). У нас это так:
Цитировать
GetA()()
А вызов процедуры - это designator [ActualParameters]designator в этом случае - GetA().

designator никак не может быть "GetA()" потому, что:
Цитировать
designator  =  qualident {selector}.
selector  =  "." ident | "[" ExpList "]" | "^" |  "(" qualident ")".
qualident  =  [ident "."] ident.
ident  =  letter {letter | digit}.
letter  =  "A" | "B" | … | "Z" | "a" | "b" | … | "z". 
digit  =   "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9".
Обращаю внимание, что qualident в selector'e в альтернативе с круглыми скобочками (пометил жирным шрифтом) НЕ опционален. То есть Selector'а вида "()" быть не может никогда.

(и да, это самый очевидный момент почему так не получится, второй, менее очевидный момент - лексемы (а лексема это "GetA", "(", ")" ) повторно не используются. )

Таким образом у нас всё заканчивается неудачей еще на стадии синтаксического анализа, не переходя к семантике (типы, вызовы и так далее).
Y = λf.(λx.f (x x)) (λx.f (x x))

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: [CP][Oberon-07/11]Procedure Type call in expression.
« Ответ #26 : Январь 14, 2013, 12:18:58 am »
Новую тему создать?
Полагаю, что да.
Y = λf.(λx.f (x x)) (λx.f (x x))

X512

  • Newbie
  • *
  • Сообщений: 45
    • Просмотр профиля

ddn

  • Jr. Member
  • **
  • Сообщений: 59
    • Просмотр профиля
Re: [CP][Oberon-07/11]Procedure Type call in expression.
« Ответ #28 : Январь 14, 2013, 01:34:42 am »
Здесь http://oberspace.dyndns.org/index.php?action=post;quote=13192;topic=427.15;last_msg=13199
последнюю цитату я ошибочно повторил, а нужно было взять другую цитату:
Да, на всякий случай - для тупых (меня) лучшим ответом будет показать AST для GetA()() в случае КП-грамматики.


Далее.

Я считаю, что вызовам процедур действительно не место в Designator, как это и сделано в 07-версии языка. Вызовы нужно помещать в выражения (в случае функций) и в операторы (в случае собственно процедур).
Если функция не выдает ссылку, то она присваивает результат недоступному (вспомогательному стековому) объекту, то есть выдает чистое значение, и Designator с такой функцией не имеет смысла подставлять в левые части оператора присвоения или на место параметров-переменных. Designator должен быть именованным объектом либо объектом к которому можно добраться через разыменования.

А вызов процедуры - это designator [ActualParameters]designator в этом случае - GetA().
designator в этом случае это GetA, а GetA() это уже designator [ActualParameters], то есть factor.

...
Цитировать
designator  =  qualident {selector}.
selector  =  "." ident | "[" ExpList "]" | "^" |  "(" qualident ")".
qualident  =  [ident "."] ident.
...
Обращаю внимание, что qualident в selector'e в альтернативе с круглыми скобочками (пометил жирным шрифтом) НЕ опционален. То есть Selector'а вида "()" быть не может никогда.
Конструкция "(" qualident ")" это проверка типа, общем случае не годится как вызов функции. Но при вызове однопараметрической функции это действительно сбивает с толку парсер, получается что парсер просто не способен разобрать такую конструкцию.

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: [CP][Oberon-07/11]Procedure Type call in expression.
« Ответ #29 : Январь 14, 2013, 01:40:58 am »
...
Цитировать
designator  =  qualident {selector}.
selector  =  "." ident | "[" ExpList "]" | "^" |  "(" qualident ")".
qualident  =  [ident "."] ident.
...
Обращаю внимание, что qualident в selector'e в альтернативе с круглыми скобочками (пометил жирным шрифтом) НЕ опционален. То есть Selector'а вида "()" быть не может никогда.
Конструкция "(" qualident ")" это проверка типа, общем случае не годится как вызов функции. Но при вызове однопараметрической функции это действительно сбивает с толку парсер, получается что парсер просто не способен разобрать такую конструкцию.
Таки да. Из за синтаксиса typeguard'ов парсер вынужден просить консультации у семантического анализатора чтобы понять, тут у нас вызов функции с одним параметром, или typeguard.

То есть чистым парсером Оберон-07 не парсится (и это не единственное такое место). Впрочем, это к данной теме уже отношения не имеет.
Y = λf.(λx.f (x x)) (λx.f (x x))