Восстановление после ошибок парсинга
От: VladD2 Российская Империя www.nemerle.org
Дата: 28.03.13 17:59
Оценка:
Всем привет.

Предположим у нас есть следующий код:

class A
{
  /*
  void Foo()
  {
  }
}


Большинство компиляторов скажут что в конце файла ожидается "*/", т.е. комментарий не закрыт.

Но в принципе тут можно восстановиться записав "/*" в грязь (т.е. проигнорировать начало комментария).

Какой вариант по вашему лучше? И какие подводные грабли тут могут возникнуть?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Восстановление после ошибок парсинга
От: Sharov Россия  
Дата: 28.03.13 18:27
Оценка: 1 (1) +3
Здравствуйте, VladD2, Вы писали:

Выдавать ошибку, так как явно, что программист намеревался что-то сделать,
но не сделал -- отвлекся и т.д. Т.е. это было некое незавершенное намерение
программиста, о котором ему лучше сообщить.
Кодом людям нужно помогать!
Re: Восстановление после ошибок парсинга
От: fin_81  
Дата: 28.03.13 18:41
Оценка:
Здравствуйте, VladD2, Вы писали:

Внутренности комментариев тоже можно компилировать. Часто там находится вполне корректный код. То есть попытаться скомпилировать как можно больший объем текста. На код внутри комментариев выдавать предупреждения. Оптимальное количество уровней предупреждений и ошибок при логировании процесса компиляции определять экспериментально на подопытных кроликах-лаборантах по красноте глаз и лица.
Re: Восстановление после ошибок парсинга
От: avpavlov  
Дата: 28.03.13 19:03
Оценка:
class A {
  public void foo() {System.out.println("A");}
}

class B extends A {
  /*
    Комментарий к перегруженной ф-ции. Если комментарий закрыть правильно, то ф-ция будет перегружена.
    Если закрыть автоматически в конце файла, то получится говно
  public void foo() {System.out.println("B");}

}
Re[2]: Восстановление после ошибок парсинга
От: avpavlov  
Дата: 28.03.13 19:05
Оценка:
Здравствуйте, avpavlov, Вы писали:


A>
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");}

}
Re[2]: Восстановление после ошибок парсинга
От: VladD2 Российская Империя www.nemerle.org
Дата: 28.03.13 20:28
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Выдавать ошибку, так как явно, что программист намеревался что-то сделать,

S>но не сделал -- отвлекся и т.д. Т.е. это было некое незавершенное намерение
S>программиста, о котором ему лучше сообщить.

Ты видимо не верно понял вопрос.

Не стоит вопрос выдавать или не выдавать сообщение об ошибке.

Вопрос в том как восстанавливать прасер.

Еще раз...

Мы можем:
1. Выдать сообщение вроде "В процессе распознавания комментария обнаружен неожиданный конец файла" и записать вес от "/*" и до конца файла в тело комментария.

2. Выдать сообщение "Обнаружена некорреткная последовательность '/*'" и продолжить парсить код так как будто "/*" не было вовсе.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Восстановление после ошибок парсинга
От: VladD2 Российская Империя www.nemerle.org
Дата: 28.03.13 20:34
Оценка:
Здравствуйте, avpavlov, Вы писали:

A>Ну и контр-пример


A>
A>  /*
A>    Эта ф-ция не нужна, но комментарий забыли закрыть после ф-ции. 
A>    Если этот комментарий проигнорировать, то ф-ция будет перегружена
A>  public void foo() {System.out.println("B");}
A>


Вот именно! У парсера нет искусственного интеллекта, так что он не может предугадать имеет ли место закоментированный код или просто комментарий забыли закрыть.

Отсюда и вопрос. Нужно ли стараться выпарсить как можно больше кода, или поступать как тупые лексерные парсеры записывая все что идет после /* в тело коментария (т.е. в грязь).

У нас просто есть такая возможность. Наш генератор парсеров генерирует безлексерные парсеры и мы можем восстанавливать парсер сильно хитрее чем это делают лексерные парсеры. Но стоит ли это делать?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Восстановление после ошибок парсинга
От: MTD https://github.com/mtrempoltsev
Дата: 29.03.13 06:22
Оценка: +6
Здравствуйте, VladD2, Вы писали:

VD>Какой вариант по вашему лучше? И какие подводные грабли тут могут возникнуть?


Мне — человеку, проще чтобы меня ткнули носом в незакрытый комментарий, чем выдали 100 наведенных ошибок из которых мне самому пришлось бы делать вывод, что нужно сделать.
Re: Восстановление после ошибок парсинга
От: Sinix  
Дата: 29.03.13 06:31
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Какой вариант по вашему лучше? И какие подводные грабли тут могут возникнуть?

Парсер не должен работать по принципу "здесь разбираем, здесь не разбираем, а тут рыбу заворачивали". Такие вещи должны определяться не возможностями парсера, а спецификацией языка. В шарпе правила обработки /* определены однозначно — комментировать отсюда и до забора */.

Конечно, можно попытаться быть умнее стандарта и если */ не найден считать концом комментария первый валидный токен. Угадать получится максимум в половине случаев. Остальные 50% придутся на закомментированный (если бы был правильно поставлен */) код и вместо одной (и довольно очевидной) ошибки пользователь получит пару сотен "Cannot resolve symbol...".
Re: Восстановление после ошибок парсинга
От: vl690001x Россия  
Дата: 29.03.13 06:33
Оценка:
Здравствуйте, VladD2, Вы писали:

Может в стандарте языка что-то по этому поводу написано? Тогда надо делать соответственно.
Но по-моему, лучше выводить ошибку, потому что налицо двусмысленность. Не каждый человек догадается что тут — забыли закрыть комментарий, или просто хотели закомментировать, но передумали. Надо предоставить решить этот вопрос программисту.
Re[4]: Восстановление после ошибок парсинга
От: avpavlov  
Дата: 29.03.13 07:13
Оценка: +3
VD>У нас просто есть такая возможность. Наш генератор парсеров генерирует безлексерные парсеры и мы можем восстанавливать парсер сильно хитрее чем это делают лексерные парсеры. Но стоит ли это делать?

Я видать не так всё понял, я думал речь идет о принудительной успешной компиляции для некоторых ошибок.

Если смотреть на это с точки зрения где остановить парсер и что подсвечивать как ошибку, то есть смысл говорить только об удобстве программиста ==> удобстве исправления. Кол-во распарсенного кода в ошибочном файле мне как-то пофигу.

Например, текущее поведение парсера Java мне нравится больше чем поведение ИДЕИ.

class A {
  public void foo() {
  } <-- ИДЕЯ ругается здесь "} expected"
  
  /* <-- Парсер Явы ругается здесь "unclosed comment"
  public void bar() {
  }
}


Мало того, что ИДЕЯ диагностировала неправильно — комментарий ниже может начинать большой Javadoc, который заканчивается где-то за пределами экрана, поэтому не видно, что он не закрыт — это затрудняет анализ и самому программисту.

Так что я за легкость исправления, а не за кол-во распарсенного кода.
Re: Восстановление после ошибок парсинга
От: C.A.B LinkedIn
Дата: 29.03.13 08:23
Оценка:
Здравствуйте, VladD2, Вы писали:
VD>Какой вариант по вашему лучше? И какие подводные грабли тут могут возникнуть?
ИМХО, для компилятора это не особо важно, всё равно на его сообщения мало кто смотрит, так что лучше сделать проще, т.е. ошибка на "/*" и дальше не разбередить(чтобы не тратить зря время программиста).
Ну а в IDE стоит подсвечивать комментарий как комментарий даже если он не закрыт, а также можно анализировать содержимое: попытаться распознать его как код и если получилось проверять как код, если нет проверять как текст(проверка орфографии). Мне лично в Eclipse не хватает такой фичи.
Между тем,что я думаю,тем,что я хочу сказать,тем,что я,как мне кажется,говорю,и тем,что вы хотите услышать,тем,что как вам кажется,вы слышите,тем,что вы понимаете,стоит десять вариантов возникновения непонимания.Но всё-таки давайте попробуем...(Э.Уэллс)
Re[5]: Восстановление после ошибок парсинга
От: Ziaw Россия  
Дата: 29.03.13 15:07
Оценка:
Здравствуйте, avpavlov, Вы писали:


A>Если смотреть на это с точки зрения где остановить парсер и что подсвечивать как ошибку, то есть смысл говорить только об удобстве программиста ==> удобстве исправления. Кол-во распарсенного кода в ошибочном файле мне как-то пофигу.


Не пофигу, этот же парсер будет использоваться для IDE. А при работе ошибочный код возникает очень часто. Так что вопрос совершенно не праздный.
Re[6]: Восстановление после ошибок парсинга
От: avpavlov  
Дата: 29.03.13 15:21
Оценка:
Z>Не пофигу, этот же парсер будет использоваться для IDE. А при работе ошибочный код возникает очень часто.

Ну и? ИДЕ (и парсер) должны ускорять исправление ошибок, а не устанавливать рекорды по объёмам распарсенного кода в невалидном файле. Соответственно, именно облегчение исправления должно ставиться во главу угла. Удасться обе метрики улучшить — отлично.
Re[4]: Восстановление после ошибок парсинга
От: artelk  
Дата: 29.03.13 15:26
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Отсюда и вопрос. Нужно ли стараться выпарсить как можно больше кода, или поступать как тупые лексерные парсеры записывая все что идет после /* в тело коментария (т.е. в грязь).

Я за то, чтобы поступать как тупые лексерные парсеры. Только чтобы при дабл-клике по ошибке "'*/' expected" был переход в этот незакрытый '/*', а не в конец файла.
Re[5]: Восстановление после ошибок парсинга
От: artelk  
Дата: 29.03.13 15:50
Оценка:
Здравствуйте, artelk, Вы писали:

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


VD>>Отсюда и вопрос. Нужно ли стараться выпарсить как можно больше кода, или поступать как тупые лексерные парсеры записывая все что идет после /* в тело коментария (т.е. в грязь).

A>Я за то, чтобы поступать как тупые лексерные парсеры. Только чтобы при дабл-клике по ошибке "'*/' expected" был переход в этот незакрытый '/*', а не в конец файла.
Хотя от такого поведения а бы не отказался:
namespace N
{
  class A
  {
    void F()
    {
       /*
    }
  }
}

Ошибку "expected '}'" не выводить, а то раздражает .
Т.е. если ожидается закрывающая скобка и она оказалась в конце файла при наличие назакрытого комментария, то считать ее закрытой.

Хотя могут быть нюансы:
namespace N
{
  class A
  {
    void F()
    {
       /*
    }
    /* Кстати, как это отработает? */
  }
}
/* Footer */

Наверно, можно придумать какое-то универсальное правило, которое будет подавлять лишние "expected '}'".
Re[7]: Восстановление после ошибок парсинга
От: Ziaw Россия  
Дата: 29.03.13 16:44
Оценка:
Здравствуйте, avpavlov, Вы писали:


Z>>Не пофигу, этот же парсер будет использоваться для IDE. А при работе ошибочный код возникает очень часто.


A>Ну и? ИДЕ (и парсер) должны ускорять исправление ошибок, а не устанавливать рекорды по объёмам распарсенного кода в невалидном файле. Соответственно, именно облегчение исправления должно ставиться во главу угла. Удасться обе метрики улучшить — отлично.


Я пока не делал никаких утверждения, кроме того, что как парсер распарсит неверный файл несомненно имеет важное значение в контексте его использования в IDE.
Re: Восстановление после ошибок парсинга
От: Ziaw Россия  
Дата: 29.03.13 16:46
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Какой вариант по вашему лучше? И какие подводные грабли тут могут возникнуть?


Для начала лучше всего будет самый простой и предсказуемый вариант. Переделать по сложному никогда не поздно. Дополнительные эвристики могут потом начать вылазить в самых неожиданных местах самым неожиданным образом.
Re[2]: Восстановление после ошибок парсинга
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.03.13 19:29
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Для начала лучше всего будет самый простой и предсказуемый вариант. Переделать по сложному никогда не поздно. Дополнительные эвристики могут потом начать вылазить в самых неожиданных местах самым неожиданным образом.


С точки зрения сложности разницы нет. Это вопрос интерпретации/алгоритма.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Восстановление после ошибок парсинга
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.03.13 19:31
Оценка:
Здравствуйте, artelk, Вы писали:

A>Только чтобы при дабл-клике по ошибке "'*/' expected" был переход в этот незакрытый '/*', а не в конец файла.


Это само собой.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.