Oberon space

General Category => Общий раздел => Тема начата: valexey_u от Январь 13, 2013, 07:21:03 pm

Название: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: valexey_u от Январь 13, 2013, 07:21:03 pm
vlad обнаружил странное - согласно синтаксису Oberon-07/11 для процедурных типов нельзя так:

MODULE Hello;
  TYPE ProcType = PROCEDURE () : INTEGER;
  VAR a : INTEGER;

  PROCEDURE A():INTEGER;
  BEGIN
    RETURN 42
  END A;

  PROCEDURE GetA() : ProcType;
  BEGIN
    RETURN A
  END GetA;

BEGIN
  a := GetA()();
END Hello.

Ключевая строчка: a:=GetA()(); То есть GetA возвращает переменную процедурного типа, и мы сразу же пытаемся её вызвать.

Я заметил еще более странное белое пятно в Oberon Report'e: там Вирт вообще нигде не говорит и не приводит примеров как эти самые процедурные переменные использовать. Ну, то есть надо ли там ^ ставить, как через них процедуры вызывать и так далее.

Но на этом странности не заканчиваются. На конфе был задан вопрос - а как там, в Component Pascal'e с этим делом?

Я покурил мануал, посмотрел грамматику, и вроде бы по грамматике, такое: GetA()() там тоже не должно быть можно. Однако ж в ББ все отлично прокатывает. То есть оно таки реально там работает. Хотя вроде как и не должно.

Попробовал в GPCP. Ругается. Вот так:
C:\Projects\gpcp-NET\NETexamples\hello>gpcp Hello.cp
  18   a := GetA()();
**** ----^ Expression not assign-compatible with destination
**** ----^ LHS type was INTEGER, RHS type was ProcType
#gpcp: <Hello> There was one error

То есть ожидаемо ругается не ожидаемым образом. При чем тут тип вообще? Там должна быть синтаксическая ошибка, до тайпчекера оно не должно было дойти вообще!

Попробовал в компиляторе akron1 (то есть это уже Oberon-07/11, модуль я написал так, что он спокойно компилируется и КП-компилятором и Оберон-компилятором). Ожидаемо ругается:
строка:  16
столбец: 8
несовместимость по присваиванию
Но тоже не ожидаемым образом - почему то и тут компиляция добралась до тайпчекера, синтаксический анализатор ошибку пропустил.

Почему это не должно работать в Обероне-07/11 на уровне синтаксиса:
Цитировать
expression  =  SimpleExpression [relation SimpleExpression].
relation  =  "=" | "#" | "<" | "<=" | ">" | ">=" | IN | IS.
SimpleExpression  =  ["+" | "-"] term {AddOperator term}.
AddOperator  =  "+" | "-" | OR.
term  =  factor {MulOperator factor}.
MulOperator  =  "*" | "/" | DIV | MOD | "&".
factor  =  number | string | NIL | TRUE | FALSE |
 set | designator [ActualParameters] | "(" expression ")" | "~" factor.

a := GetType()()

Справа у нас, очевидно, expression. Expression состоит из последовательности SimpleExpression'ов склеиваемых каким-нибудь relation'ом. У нас тут склейки очевидно нет, так что SimpleExpression будет только один (поэтому я его выделил жирным).

SimpleExpression состоит из последовательности term'ов, склевивыемых AddOperator'ами, который у нас тут очевидно также нет, так что term у нас будет один.

term состоит из factor'ов, склеиваемых MulOperator'ами, которых у нас тут тоже очевидно нет, следовательно factor у нас также один.

А factor у нас может быть много чем, но только одним чем-нибудь за раз, например десигнатором с опциональными актуальными параметрами (designator [ActualParameters]), что мы и имеем.

Внимание вопрос - каким образом сюда получилось на уровне синтаксиса прилепить еще одну пару скобочек так, что это не привело к синтаксической ошибке?

Такое ощущение складывается, что в этом месте есть баг в ББ, есть баг в GPCP и есть баг в компиляторе akorn1. Причем в двух последних баг одинаковых (на РАЗНЫХ грамматиках!)
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: valexey_u от Январь 13, 2013, 07:25:21 pm
a := GetType()()

Справа у нас, ...

a:=GetA()() конечно же.
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: ddn от Январь 13, 2013, 09:57:50 pm
Интересовался этим вопросом, и помню, что в ББ вызов процедур и функций всегда сидел в Designator:
Designator = Qualident {"." ident | "[" ExprList "]" | "^"
| "("Qualident ")" | "(" [ExprList] ")"} [ "$" ].
В секции "(" [ExprList] ")". Так что несколько вызовов подряд соответствуют синтакису.
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: Valery Solovey от Январь 13, 2013, 10:05:21 pm
Не должен ругаться на синтаксическую ошибку.
Сначала синтаксический анализатор выбирает все лексемы, которые допустимы в этом месте. Потом выполняет контекстную проверку. На контекстной проверке и выскочила ошибка. Но если бы в Обероне обязательным было завершать любой оператор точкой с запятой, то при встрече второй пары скобок он бы ругнулся на неправильный синтаксис.

Я исходники не смотрел, но кажется знаю, где исправлять.

Однако, сначала проверю, ругнётся ли он на синтаксис, если я заменю у A и a тип результата с INTEGER на ProcType.
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: vlad от Январь 13, 2013, 10:24:37 pm
Не должен ругаться на синтаксическую ошибку.

Согласен. Если бы слева был процедерный тип (т.е. присваивание допустимо), то тогда да - была бы ошибка синтаксиса. Или если бы это был стэйтмент: GetA()()

Тем не менее вопрос остается - почему Вирт так сделал? Особенно коряво получается для случая POINTER TO PROCEDURE - сначала надо разыменовать в отдельную переменную, потом только можно сделать вызов.
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: vlad от Январь 13, 2013, 10:35:10 pm
Особенно коряво получается для случая POINTER TO PROCEDURE.

Хотя нет. POINTER TO PROCEDURE сам по себе не очень актуален (при наличи процедурных переменных). Но в тех редких случаях, когда он будет нужен - таки будет коряво.
Короче, ставлю на то, что Вирту оно было не нужно (в реализации его компиялтора) - и он просто не стал усложнять грамматику (как заметил ddn - в ББ это разруливается через designator).
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: valexey_u от Январь 13, 2013, 10:35:39 pm
Интересовался этим вопросом, и помню, что в ББ вызов процедур и функций всегда сидел в Designator:
Designator = Qualident {"." ident | "[" ExprList "]" | "^"
| "("Qualident ")" | "(" [ExprList] ")"} [ "$" ].
В секции "(" [ExprList] ")". Так что несколько вызовов подряд соответствуют синтакису.
А можно на пальцах, для особо тупых? Разве секция "(" [ExprList] ")" не породит нам вложенные скобочки? Как эта грамматика породит нам GetA()() ?
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: valexey_u от Январь 13, 2013, 10:40:42 pm
Не должен ругаться на синтаксическую ошибку.
Сначала синтаксический анализатор выбирает все лексемы, которые допустимы в этом месте. Потом выполняет контекстную проверку. На контекстной проверке и выскочила ошибка. Но если бы в Обероне обязательным было завершать любой оператор точкой с запятой, то при встрече второй пары скобок он бы ругнулся на неправильный синтаксис.
Стоп-стоп-стоп. Предположим у нас просто парсер, а не компилятор. На выходе он должен тупо выдать AST. Естественно никакого семантического анализатора у него там нет, и тем более тайп-чекера. Внимание вопрос - он тут найдет ошибку? И если нет, то какое дерево он нам построит?

Однако, сначала проверю, ругнётся ли он на синтаксис, если я заменю у A и a тип результата с INTEGER на ProcType.
Компилятор akorn1 ругается на рекурсивное определение типа (и я не уверен что это корректно).
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: Valery Solovey от Январь 13, 2013, 10:41:14 pm
Ну вот:MODULE Hello;
  TYPE ProcType = PROCEDURE () : INTEGER;
  MetaProcType = PROCEDURE () : ProcType;
  VAR a : ProcType;

  PROCEDURE A():INTEGER;
  BEGIN
    RETURN 42
  END A;

  PROCEDURE GetA() : ProcType;
  BEGIN
    RETURN A
  END GetA;

  PROCEDURE GetGetA() : MetaProcType;
  BEGIN
    RETURN GetA
  END GetGetA;

BEGIN
  a := GetA()();
END Hello.
Добавил процедуру и тип. Теперь, как я и предполагал, ругается на пространство между парами скобочек.
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: valexey_u от Январь 13, 2013, 10:42:11 pm
Интересовался этим вопросом, и помню, что в ББ вызов процедур и функций всегда сидел в Designator:
Designator = Qualident {"." ident | "[" ExprList "]" | "^"
| "("Qualident ")" | "(" [ExprList] ")"} [ "$" ].
В секции "(" [ExprList] ")". Так что несколько вызовов подряд соответствуют синтакису.
Да, на всякий случай - для тупых (меня) лучшим ответом будет показать AST для GetA()() в случае КП-грамматики.
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: X512 от Январь 13, 2013, 10:44:37 pm
Oberon-07 выглядит ощутимо хуже предыдущих оберонов. Зачем его использовать для не микроконтроллерного софта мне не понятно. По мне так самый лучший оберон это Component Pascal, хотя недостатков в нём тоже хватает. Например недостаточно проработаны записи, размещаемые не через NEW().
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: Valery Solovey от Январь 13, 2013, 10:48:07 pm
Тем не менее вопрос остается - почему Вирт так сделал?
А это точно сделал Вирт? Я просто вопроса досконально не знаю. Может, просто в реализациях не досмотрели. Ведь не во всех языках бывает "and we need to go deeper".
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: valexey_u от Январь 13, 2013, 10:52:48 pm
Oberon-07 выглядит ощутимо хуже предыдущих оберонов. Зачем его использовать для не микроконтроллерного софта мне не понятно. По мне так самый лучший оберон это Component Pascal, хотя недостатков в нём тоже хватает. Например недостаточно проработаны записи, размещаемые не через NEW().
Ну, КП как минимум абсолютно не портабельный, да и существенно более сложный (и для реализации и для изучения).

С другой стороны, я не вижу у Оберона-07/11 преимуществ для микроконтроллеров перед другими языками.
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: valexey_u от Январь 13, 2013, 10:56:37 pm
Тем не менее вопрос остается - почему Вирт так сделал?
А это точно сделал Вирт? Я просто вопроса досконально не знаю. Может, просто в реализациях не досмотрели. Ведь не во всех языках бывает "and we need to go deeper".
Вопрос появился не после того как в конкретной реализации напоролись на проблему, вопрос появился после того, как при создании своей реализации напоролись на проблему в Language report.

Проверять правильность программы опираясь на какую-либо реализацию языка в принципе нельзя, ибо нет гарантии что в реализации нет ошибок.

Я же кажется упоминал, что я, да и Влад, изучаем Oberon-07/11 преимущественно по language report'у :-) КП, кстати, тоже (когда требуется посмотреть, а как там у большого брата сделано).
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: Valery Solovey от Январь 13, 2013, 11:02:03 pm
Стоп-стоп-стоп. Предположим у нас просто парсер, а не компилятор. На выходе он должен тупо выдать AST. Естественно никакого семантического анализатора у него там нет, и тем более тайп-чекера. Внимание вопрос - он тут найдет ошибку? И если нет, то какое дерево он нам построит?
Так или иначе в данном месте исходника выскочит ошибка. Вопрос только: на каком уровне?

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

То есть, по-моему, хоть какая-то контекстная проверка выполняться должна: прочли текущую лексему и изменили список ожидаемых лексем за нею.
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: Valery Solovey от Январь 13, 2013, 11:05:10 pm
Добавить родственником давнего предка (следующий оператор текущей процедуры)?
Хотя нет, для этого нужно встретить точку с запятой.
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: X512 от Январь 13, 2013, 11:07:40 pm
Ну, КП как минимум абсолютно не портабельный
В каком плане не портабельный? Плохо запускается не разных ОС или сложно написать новый backend?
, да и существенно более сложный (и для реализации и для изучения).
Никто же не заставляет вам его реализовывать. Вы же не пишете для себя компилятор C++ например, не так ли?

Относительно простоты для обучения: я здесь не вижу каких-либо проблем. Базовые конструкции те же, что и в предыдущих оберонах, а ООП для обучения использовать никто не заставляет. Впрочем ООП в Component Pascal очень мощный и простой по сравнению с другими ЯП(С++, Java). ООП это основное преимущество Component Pascal'я перед остальными оберонами.
С другой стороны, я не вижу у Оберона-07/11 преимуществ для микроконтроллеров перед другими языками.
Здесь как раз простота реализации компилятора - очень важное преимущество. Микроконтроллеров много всяких бывает. А полноценных процессора сейчас только три: i386, AMD64 и ARM. Остальные(SPARC, Power PC и т. д.) либо померли, либо имеют специфическое применение.
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: valexey_u от Январь 13, 2013, 11:14:30 pm
Стоп-стоп-стоп. Предположим у нас просто парсер, а не компилятор. На выходе он должен тупо выдать AST. Естественно никакого семантического анализатора у него там нет, и тем более тайп-чекера. Внимание вопрос - он тут найдет ошибку? И если нет, то какое дерево он нам построит?
Так или иначе в данном месте исходника выскочит ошибка. Вопрос только: на каком уровне?

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

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

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

Все же очень просто: есть токенизатор (ака лексер) распознал лексему - отдал её большому дяде, под названием парсер/синтаксический анализатор. А вот что уже он будет с ней делать, зависит от того какого он типа. Если это примитивный LL(1) в виде рекурсивного спуска, то он будет сравнивать текущую лексему с тем что ожидалось в данном правиле. если ожидалось не то, то перейдет к следующей альтернативе правила. Если это более умная, табличная реализация LL(1)/LL(k), то там все будет похитрее (http://ru.wikipedia.org/wiki/LL-%D0%B0%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%82%D0%BE%D1%80#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80). Есть это LALR, то там будут попытки сверток, то есть совсем иначе. Если это GLR, то еще по другому (будет порождаться потенциально множество альтернативных AST). А если там GLL-алгоритм (который совсем свежий - 2010 год по моему) то там тоже будет нечто свое.

Но при чем тут все эти детали синтаксического анализа применительно к нашей задаче? Ни одна из них в данном случае не требует иметь внесинтаксического контекста (то есть задействовать семантический анализатор) для того, чтобы понять, что AST для данной грамматики по данной входной строке не построить.
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: Valery Solovey от Январь 13, 2013, 11:20:15 pm
Интересовался этим вопросом, и помню, что в ББ вызов процедур и функций всегда сидел в Designator:
Designator = Qualident {"." ident | "[" ExprList "]" | "^"
| "("Qualident ")" | "(" [ExprList] ")"} [ "$" ].
В секции "(" [ExprList] ")". Так что несколько вызовов подряд соответствуют синтакису.
Просмотрел по диагонали сообщение 07. Похоже, что в нём эквивалентная структура.
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: valexey_u от Январь 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 более-менее подходит и для того и другого.

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

Короче, я пытался построить AST (руками естественно, парсеры и компиляторы побоку) по Оберон-грамматики для этого случая (GetA()()) и для КП-версии грамматики. У меня не получилось. Если у кого-то получится, прошу поделиться оным AST. Это будет доказательство того, что данная конструкция в данном языке валидна.
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: ddn от Январь 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 = [ "$" ].
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: valexey_u от Январь 13, 2013, 11:33:38 pm
Интересовался этим вопросом, и помню, что в ББ вызов процедур и функций всегда сидел в Designator:
Designator = Qualident {"." ident | "[" ExprList "]" | "^"
| "("Qualident ")" | "(" [ExprList] ")"} [ "$" ].
В секции "(" [ExprList] ")". Так что несколько вызовов подряд соответствуют синтакису.
А можно на пальцах, для особо тупых? Разве секция "(" [ExprList] ")" не породит нам вложенные скобочки? Как эта грамматика породит нам GetA()() ?
Что вы имеете ввиду под вложенными скобочками? Если квадратные скобки вложенные в круглые, то квадратные здесь не заключены в кавычки и не войдут в слово языка КП, они суть операторы языка РФБН. Если вы о последовательно идущих круглых скобках, то не забывайте, что этот вариант альтернативы заключен в фигурные скобки, т.е. в оператор бесконечного повторения.
{... "(" [ExprList] ")"}
Да, спасибо, это я просмотрел.

Выходит, что в большой вероятностью (нужно еще семантику рассмотреть) в GPCP ошибка.
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: Valery Solovey от Январь 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().
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: X512 от Январь 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 использовать нельзя.

Впрочем, мы отклонились от темы.
Новую тему создать?
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: valexey_u от Январь 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", "(", ")" ) повторно не используются. )

Таким образом у нас всё заканчивается неудачей еще на стадии синтаксического анализа, не переходя к семантике (типы, вызовы и так далее).
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: valexey_u от Январь 14, 2013, 12:18:58 am
Новую тему создать?
Полагаю, что да.
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: X512 от Январь 14, 2013, 12:39:14 am
Полагаю, что да.
http://oberspace.dyndns.org/index.php/topic,428.0.html (http://oberspace.dyndns.org/index.php/topic,428.0.html)
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: ddn от Январь 14, 2013, 01:34:42 am
Здесь http://oberspace.dyndns.org/index.php?action=post;quote=13192;topic=427.15;last_msg=13199 (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 ")" это проверка типа, общем случае не годится как вызов функции. Но при вызове однопараметрической функции это действительно сбивает с толку парсер, получается что парсер просто не способен разобрать такую конструкцию.
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: valexey_u от Январь 14, 2013, 01:40:58 am
...
Цитировать
designator  =  qualident {selector}.
selector  =  "." ident | "[" ExpList "]" | "^" |  "(" qualident ")".
qualident  =  [ident "."] ident.
...
Обращаю внимание, что qualident в selector'e в альтернативе с круглыми скобочками (пометил жирным шрифтом) НЕ опционален. То есть Selector'а вида "()" быть не может никогда.
Конструкция "(" qualident ")" это проверка типа, общем случае не годится как вызов функции. Но при вызове однопараметрической функции это действительно сбивает с толку парсер, получается что парсер просто не способен разобрать такую конструкцию.
Таки да. Из за синтаксиса typeguard'ов парсер вынужден просить консультации у семантического анализатора чтобы понять, тут у нас вызов функции с одним параметром, или typeguard.

То есть чистым парсером Оберон-07 не парсится (и это не единственное такое место). Впрочем, это к данной теме уже отношения не имеет.
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: Geniepro от Январь 14, 2013, 05:57:58 am
А полноценных процессора сейчас только три: i386, AMD64 и ARM. Остальные(SPARC, Power PC и т. д.) либо померли, либо имеют специфическое применение.
MIPS и SPARC ни разу не померли. MIPS очень активно используется в КИтае -- самом большом в мире рынке электроники. Откройте свой wifi-роутер и обнаружите там именно MIPS.
SPARC-чипы российского производства активно используется военными в России.
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: Valery Solovey от Январь 14, 2013, 10:37:22 am
То есть чистым парсером Оберон-07 не парсится (и это не единственное такое место). Впрочем, это к данной теме уже отношения не имеет.
Парсится. Просто, на следующем этапе после синтаксического анализа придётся ползать по дереву и собирать информацию, которая у нас есть уже сейчас.
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: Valery Solovey от Январь 14, 2013, 10:41:53 am
Я считаю, что вызовам процедур действительно не место в Designator, как это и сделано в 07-версии языка. Вызовы нужно помещать в выражения (в случае функций) и в операторы (в случае собственно процедур).
Подозреваю, что тогда не получится LL(1).
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: Губанов Сергей Юрьевич от Январь 14, 2013, 12:38:12 pm
POINTER TO PROCEDURE
Поинтеров на процедуру не бывает.

Компилятор akorn1 ругается на рекурсивное определение типа (и я не уверен что это корректно).
Тем хуже для компилятора akorn1. Процедурный тип возвращающий переменную этого же типа

P = PROCEDURE(): P;

ничем не хуже типа

X = POINTER TO RECORD x: X END.

Тип P может использоваться для программирования цепочек вычислений а-ля конечный автомат.

В C# объявить такой тип тоже можно:

delegate P P ();
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: akron1 от Январь 14, 2013, 01:27:44 pm
Тем хуже для компилятора akorn1. Процедурный тип возвращающий переменную этого же типа

P = PROCEDURE(): P;

ничем не хуже типа

X = POINTER TO RECORD x: X END.

Тип P может использоваться для программирования цепочек вычислений а-ля конечный автомат.

В C# объявить такой тип тоже можно:

delegate P P ();


Согласен, здесь я ошибся.
Сейчас посмотрел, как это обрабатывается в Astrobe (ver 4.0.2):

TYPE
P = PROCEDURE(): P;
X = POINTER TO RECORD x: X END.

компилируется без ошибок

TYPE
R = RECORD x: R END;
A = ARRAY 10 OF A;
VAR v:v;

Сообщение компилятора:
"Error: not a type or undefined"

CONST c = c;

А вот здесь Astrobe упал.
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: vlad от Январь 14, 2013, 11:18:21 pm
Поинтеров на процедуру не бывает.

А. Точно :)
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: DddIzer от Январь 15, 2013, 08:49:38 am
Поинтеров на процедуру не бывает.

А. Точно :)
ну  да - она сама (точнее , переменная проц. типа) есть разновидность указателя... согласно общей схеме высокоуровневой интерпретации  базовых понятий ЯВУ
Название: Re: [CP][Oberon-07/11]Procedure Type call in expression.
Отправлено: vlad от Июль 14, 2013, 06:31:47 am
Я тут обнаружил еще более несовместимый с практикой косяк (из той же оперы): нельзя разыменовать указатель, который вернула процедура. Т.е. вот такой банальный код не работает:
make().do();
f(make()^);

Только через временный указатель. Ужос.