Выдавать ошибку, так как явно, что программист намеревался что-то сделать,
но не сделал -- отвлекся и т.д. Т.е. это было некое незавершенное намерение
программиста, о котором ему лучше сообщить.
Внутренности комментариев тоже можно компилировать. Часто там находится вполне корректный код. То есть попытаться скомпилировать как можно больший объем текста. На код внутри комментариев выдавать предупреждения. Оптимальное количество уровней предупреждений и ошибок при логировании процесса компиляции определять экспериментально на подопытных кроликах-лаборантах по красноте глаз и лица.
class A {
public void foo() {System.out.println("A");}
}
class B extends A {
/*
Комментарий к перегруженной ф-ции. Если комментарий закрыть правильно, то ф-ция будет перегружена.
Если закрыть автоматически в конце файла, то получится говно
public void foo() {System.out.println("B");}
}
A>class A {
A> public void foo() {System.out.println("A");}
A>}
A>class B extends A {
A> /*
A> Комментарий к перегруженной ф-ции. Если комментарий закрыть правильно, то ф-ция будет перегружена.
A> Если закрыть автоматически в конце файла, то получится говно
A> public void foo() {System.out.println("B");}
A>}
A>
Ну и контр-пример
public void foo() {System.out.println("A");}
}
class B extends A {
/*
Эта ф-ция не нужна, но комментарий забыли закрыть после ф-ции.
Если этот комментарий проигнорировать, то ф-ция будет перегружена
public void foo() {System.out.println("B");}
}
Здравствуйте, Sharov, Вы писали:
S>Выдавать ошибку, так как явно, что программист намеревался что-то сделать, S>но не сделал -- отвлекся и т.д. Т.е. это было некое незавершенное намерение S>программиста, о котором ему лучше сообщить.
Ты видимо не верно понял вопрос.
Не стоит вопрос выдавать или не выдавать сообщение об ошибке.
Вопрос в том как восстанавливать прасер.
Еще раз...
Мы можем:
1. Выдать сообщение вроде "В процессе распознавания комментария обнаружен неожиданный конец файла" и записать вес от "/*" и до конца файла в тело комментария.
2. Выдать сообщение "Обнаружена некорреткная последовательность '/*'" и продолжить парсить код так как будто "/*" не было вовсе.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, avpavlov, Вы писали:
A>Ну и контр-пример
A>
A> /*
A> Эта ф-ция не нужна, но комментарий забыли закрыть после ф-ции.
A> Если этот комментарий проигнорировать, то ф-ция будет перегружена
A> public void foo() {System.out.println("B");}
A>
Вот именно! У парсера нет искусственного интеллекта, так что он не может предугадать имеет ли место закоментированный код или просто комментарий забыли закрыть.
Отсюда и вопрос. Нужно ли стараться выпарсить как можно больше кода, или поступать как тупые лексерные парсеры записывая все что идет после /* в тело коментария (т.е. в грязь).
У нас просто есть такая возможность. Наш генератор парсеров генерирует безлексерные парсеры и мы можем восстанавливать парсер сильно хитрее чем это делают лексерные парсеры. Но стоит ли это делать?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Какой вариант по вашему лучше? И какие подводные грабли тут могут возникнуть?
Мне — человеку, проще чтобы меня ткнули носом в незакрытый комментарий, чем выдали 100 наведенных ошибок из которых мне самому пришлось бы делать вывод, что нужно сделать.
Здравствуйте, VladD2, Вы писали:
VD>Какой вариант по вашему лучше? И какие подводные грабли тут могут возникнуть?
Парсер не должен работать по принципу "здесь разбираем, здесь не разбираем, а тут рыбу заворачивали". Такие вещи должны определяться не возможностями парсера, а спецификацией языка. В шарпе правила обработки /* определены однозначно — комментировать отсюда и до забора */.
Конечно, можно попытаться быть умнее стандарта и если */ не найден считать концом комментария первый валидный токен. Угадать получится максимум в половине случаев. Остальные 50% придутся на закомментированный (если бы был правильно поставлен */) код и вместо одной (и довольно очевидной) ошибки пользователь получит пару сотен "Cannot resolve symbol...".
Может в стандарте языка что-то по этому поводу написано? Тогда надо делать соответственно.
Но по-моему, лучше выводить ошибку, потому что налицо двусмысленность. Не каждый человек догадается что тут — забыли закрыть комментарий, или просто хотели закомментировать, но передумали. Надо предоставить решить этот вопрос программисту.
VD>У нас просто есть такая возможность. Наш генератор парсеров генерирует безлексерные парсеры и мы можем восстанавливать парсер сильно хитрее чем это делают лексерные парсеры. Но стоит ли это делать?
Я видать не так всё понял, я думал речь идет о принудительной успешной компиляции для некоторых ошибок.
Если смотреть на это с точки зрения где остановить парсер и что подсвечивать как ошибку, то есть смысл говорить только об удобстве программиста ==> удобстве исправления. Кол-во распарсенного кода в ошибочном файле мне как-то пофигу.
Например, текущее поведение парсера Java мне нравится больше чем поведение ИДЕИ.
class A {
public void foo() {
} <-- ИДЕЯ ругается здесь "} expected"
/* <-- Парсер Явы ругается здесь "unclosed comment"public void bar() {
}
}
Мало того, что ИДЕЯ диагностировала неправильно — комментарий ниже может начинать большой Javadoc, который заканчивается где-то за пределами экрана, поэтому не видно, что он не закрыт — это затрудняет анализ и самому программисту.
Так что я за легкость исправления, а не за кол-во распарсенного кода.
Здравствуйте, VladD2, Вы писали: VD>Какой вариант по вашему лучше? И какие подводные грабли тут могут возникнуть?
ИМХО, для компилятора это не особо важно, всё равно на его сообщения мало кто смотрит, так что лучше сделать проще, т.е. ошибка на "/*" и дальше не разбередить(чтобы не тратить зря время программиста).
Ну а в IDE стоит подсвечивать комментарий как комментарий даже если он не закрыт, а также можно анализировать содержимое: попытаться распознать его как код и если получилось проверять как код, если нет проверять как текст(проверка орфографии). Мне лично в Eclipse не хватает такой фичи.
Между тем,что я думаю,тем,что я хочу сказать,тем,что я,как мне кажется,говорю,и тем,что вы хотите услышать,тем,что как вам кажется,вы слышите,тем,что вы понимаете,стоит десять вариантов возникновения непонимания.Но всё-таки давайте попробуем...(Э.Уэллс)
A>Если смотреть на это с точки зрения где остановить парсер и что подсвечивать как ошибку, то есть смысл говорить только об удобстве программиста ==> удобстве исправления. Кол-во распарсенного кода в ошибочном файле мне как-то пофигу.
Не пофигу, этот же парсер будет использоваться для IDE. А при работе ошибочный код возникает очень часто. Так что вопрос совершенно не праздный.
Z>Не пофигу, этот же парсер будет использоваться для IDE. А при работе ошибочный код возникает очень часто.
Ну и? ИДЕ (и парсер) должны ускорять исправление ошибок, а не устанавливать рекорды по объёмам распарсенного кода в невалидном файле. Соответственно, именно облегчение исправления должно ставиться во главу угла. Удасться обе метрики улучшить — отлично.
Здравствуйте, VladD2, Вы писали:
VD>Отсюда и вопрос. Нужно ли стараться выпарсить как можно больше кода, или поступать как тупые лексерные парсеры записывая все что идет после /* в тело коментария (т.е. в грязь).
Я за то, чтобы поступать как тупые лексерные парсеры. Только чтобы при дабл-клике по ошибке "'*/' expected" был переход в этот незакрытый '/*', а не в конец файла.
Здравствуйте, artelk, Вы писали:
A>Здравствуйте, VladD2, Вы писали:
VD>>Отсюда и вопрос. Нужно ли стараться выпарсить как можно больше кода, или поступать как тупые лексерные парсеры записывая все что идет после /* в тело коментария (т.е. в грязь). A>Я за то, чтобы поступать как тупые лексерные парсеры. Только чтобы при дабл-клике по ошибке "'*/' expected" был переход в этот незакрытый '/*', а не в конец файла.
Хотя от такого поведения а бы не отказался:
namespace N
{
class A
{
void F()
{
/*
}
}
}
Ошибку "expected '}'" не выводить, а то раздражает .
Т.е. если ожидается закрывающая скобка и она оказалась в конце файла при наличие назакрытого комментария, то считать ее закрытой.
Хотя могут быть нюансы:
namespace N
{
class A
{
void F()
{
/*
}
/* Кстати, как это отработает? */
}
}
/* Footer */
Наверно, можно придумать какое-то универсальное правило, которое будет подавлять лишние "expected '}'".
Z>>Не пофигу, этот же парсер будет использоваться для IDE. А при работе ошибочный код возникает очень часто.
A>Ну и? ИДЕ (и парсер) должны ускорять исправление ошибок, а не устанавливать рекорды по объёмам распарсенного кода в невалидном файле. Соответственно, именно облегчение исправления должно ставиться во главу угла. Удасться обе метрики улучшить — отлично.
Я пока не делал никаких утверждения, кроме того, что как парсер распарсит неверный файл несомненно имеет важное значение в контексте его использования в IDE.
Здравствуйте, VladD2, Вы писали:
VD>Какой вариант по вашему лучше? И какие подводные грабли тут могут возникнуть?
Для начала лучше всего будет самый простой и предсказуемый вариант. Переделать по сложному никогда не поздно. Дополнительные эвристики могут потом начать вылазить в самых неожиданных местах самым неожиданным образом.
Здравствуйте, Ziaw, Вы писали:
Z>Для начала лучше всего будет самый простой и предсказуемый вариант. Переделать по сложному никогда не поздно. Дополнительные эвристики могут потом начать вылазить в самых неожиданных местах самым неожиданным образом.
С точки зрения сложности разницы нет. Это вопрос интерпретации/алгоритма.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.