Re[25]: Вопрос о конкретных примерах
От: Nick_ Россия  
Дата: 08.10.04 04:50
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Nick_, Вы писали:


N_>>OK. Обьясняю еще раз. на этот раз разжовываю как совсем чайнику.

N_>>Берем стандарт С++. Читаем Appendix A: Grammar summary

N_>>Компилятор разбирает выражение (hello.... перед ним стоит открывающая скобка.


VD>Ну, это 100%-ный вызов функции.

Ты бредишь?

N_>>Дальше он может идти по одному из двух путей


N_>>Если hello — тип:

N_>>expression->...->cast-expression->(->type-id->...->type-name->hello.
N_>>Если hello — идентификатор(переменная):
N_>>expression->...->cast-expression->...->primary-expression->(->expression->...->id-expression->hello.

VD>Ты наверно имешь в виду двусмысленность в трактовании выражения в скобках идущее перед идентификатором или другими скобками.

Это как? Выражение в скобках (exp) идущее перед идентификатором или другими скобками...
(expr)id или (expr)(...
Слушай, я об одном, а ты о другом. Попробуй еще раз почитать что я написал.
Я о двусмысленности трактования идентификатора в скобках, при разборе выражения.
(hello)...
Это может быть либо c-style-cast либо переменная в скобках.

VD>Дык тут в станадрте должно быть написано, что имеет место двусмысленность (ambiguities). Под рукой плюсового стандарта нет, так что точную формулировку привести не могу.

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

VD>Так вот, чтобы разрешить эту двусмысленность компилятору нужно провести семантический анализ и определить является ли выражение в скобках типом или нет. Ситуация вроде "(Type)id" решается и без анализа. Но "(Type)-id" уже двусмысленна.

О том я и говорю. Так вот в шаблоне, компилятор не может определить тип или не тип стоит в скобках.
Я уже приводил пример с (T::x)+1; Поэтому компилятор не может сделать синтаксический разбор. А семантический разбор может быть проведен только при инстанциации. Никакие эвристики тут не помогут. Некоторые компиляторы С++ стоят AST в предположении что T::x это переменная, а потом выкидывают эти результаты и парсят заново шаблон при инстанциации. Некоторые вообще не парсят шаблон до инстанциации.
Если не веришь, то можешь попробовать взять сановский компилятор С++ Forte и проверить.
template<class T>
class A
{
this is a test;
};
Скомпилируется без ошибок.

VD>Это нормально. И не в коем случае не противоречит моим словам. Синтаксический разбор при этом остается синтаксическим рабзбором, а семантический анализ — семантическим анализом который проходит исключительно после стадии синтаксического разбора (иначе как собственно установить, был ли вообще объевлян Type?). Просто С++ довольно древний язык и в нем используемый тип обязан быть объявлен (продекларирован) до его использования. В C#, например, все намного сложнее. В нем тип не обязан быть объявлен до использования. По этому для начала семантического анализа требуется полностью закончить стадию синтаксического разбора.

Еще пример:
01 typedef int free;
02 void main()
03 {
04 free(ptr);
05 }
Компилятор не может сделать семантический анализ четвертой строки до синтаксического анализа четвертой строки. Это как ты утверждаешь и я с этим согласен.
Но компилятор не может сделать синтаксический анализ четвертой строки до семантического анализа первой.
Ну не может для такой программы семантический анализ быть "исключительно после" синтаксического.

N_>>Ну и как определить по какому пути делать , не зная hello тип или не тип?


VD>Только проведением семантического анализа. Но он может быть проведен только для части кода разобранной с помощью синтаксического разбора.

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

N_>>Еще в качестве примера могу привести приоритет операций.

N_>> То, что умножение имеет более высокий приоритет чем сложение выясняется уже на этапе синтаксического анализа, а не семантического.

VD>Это выясняется на этапе составления граматики языка. А парсер всего лишь отражает спецификацию. К семантике приоритеты не имеют ни малейшего отношения.

Ну почему же? Кто мешает составить грамматику так, что бы в ней не отражался приоритет операций? Тогда приоритет будет делом семантического анализа. И такие языки есть, в которых можно менять приоритеты операций. Например пролог.

N_>>После того как я тебе еще раз попытался разжевать, может ты потрудишься обьяснить что ты имел в виду в

N_>>сообщении http://rsdn.ru/Forum/Message.aspx?mid=840770&amp;only=1
Автор: VladD2
Дата: 06.10.04
когда заявил, что "Да пофигу для синтаксического разбора чем будет эта конструкция. Тип, не тип — это уже семантика."


VD>В приведенном тобой примере никакой двусмысленности нет и семантический анализ не трелуется. Из контекста четко видно, чем должен быть идентификатор. Так что код будет спокойно распарсен в АСТ и кога пойдет воплощение шаблона просто будет проверено, что данный идинтификатор действительно существует и является типом. А для разрешения неоднозначностей как раз и был введен typename.

В каком из примеров нет двусмысленности? В этом?
template<class T>
class A
{
int x = (T::x)+1;
};
А если пойдет воплощение шаблона, и окажется что идентификатор — не то о чем компилятор подумал при первом проходе?

А вот например, если бы параметров у шаблона было 5, то вариантов разбора было бы 2^5 = 32. Зачем запоминать AST, при первом проходе, а потом проверять при инстанциации, если скорее всего он никогда не понадобится и придется заново делать разбор?

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