Восстановление после ошибок парсинга
От: 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" был переход в этот незакрытый '/*', а не в конец файла.


Это само собой.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Восстановление после ошибок парсинга
От: ononim  
Дата: 29.03.13 20:21
Оценка:
VD>Мы можем:
VD>1. Выдать сообщение вроде "В процессе распознавания комментария обнаружен неожиданный конец файла" и записать вес от "/*" и до конца файла в тело комментария.

VD>2. Выдать сообщение "Обнаружена некорреткная последовательность '/*'" и продолжить парсить код так как будто "/*" не было вовсе.


3. Выдать сообщение "Обнаружена некорреткная последовательность '/*'" и продолжить парсить код так как будто "/*" не было вовсе. И в в самом конце зафэйлить компиляцию. Профит — сразу обнаружим все (или большинство) синтаксические ошибки..
Как много веселых ребят, и все делают велосипед...
Re[3]: Восстановление после ошибок парсинга
От: Ziaw Россия  
Дата: 29.03.13 22:28
Оценка:
Здравствуйте, VladD2, Вы писали:

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


VD>С точки зрения сложности разницы нет. Это вопрос интерпретации/алгоритма.


Как сказать. Одна поставленная непарная скобка может заставить парсер игнорировать совершенно невинную скобку в другом конце файла, что может привести к неразберихе. Мы ведь точно можем только сказать, что они не парные, а какой скобке нет пары могут быть разные предположения.
Re: Восстановление после ошибок парсинга
От: __kot2  
Дата: 29.03.13 23:35
Оценка: +1
Здравствуйте, VladD2, Вы писали:
VD>Большинство компиляторов скажут что в конце файла ожидается "*/", т.е. комментарий не закрыт.
VD>Но в принципе тут можно восстановиться записав "/*" в грязь (т.е. проигнорировать начало комментария).
VD>Какой вариант по вашему лучше? И какие подводные грабли тут могут возникнуть?
я когда был маленький, то думал, что компилятор должен сам уметь за меня ошибки исправлять. типа я понапишу че-нить, он мне сам все поправит чтобы корректно было и у меня все заработает
но когда я вырос я понял, что единственное что мне надо от компилятора это указание места ошибки. мне даже текста не нужно, и так сразу все бывает понятно.
не должен компилятор самодеятельностью заниматься.
Re[4]: Восстановление после ошибок парсинга
От: VladD2 Российская Империя www.nemerle.org
Дата: 30.03.13 01:34
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Как сказать. Одна поставленная непарная скобка может заставить парсер игнорировать совершенно невинную скобку в другом конце файла, что может привести к неразберихе. Мы ведь точно можем только сказать, что они не парные, а какой скобке нет пары могут быть разные предположения.


Мы на уровне скобок не оперируем. Но думаю, что удастся создать очень приличную систему автоматического восстановления после ошибок.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Восстановление после ошибок парсинга
От: WolfHound  
Дата: 30.03.13 11:23
Оценка:
Здравствуйте, __kot2, Вы писали:

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

С этим согласен.
Но нужно не забывать, что от точности восстановления зависит правильность ошибки.

__>не должен компилятор самодеятельностью заниматься.

Есть такой недокомпилятор, IDE называется. Так вот, он должен.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[4]: Восстановление после ошибок парсинга
От: kochetkov.vladimir Россия https://kochetkov.github.io
Дата: 30.03.13 18:14
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>У нас просто есть такая возможность. Наш генератор парсеров генерирует безлексерные парсеры и мы можем восстанавливать парсер сильно хитрее чем это делают лексерные парсеры. Но стоит ли это делать?


В конкретном исходном примере с многострочным комментарием в си-подобном коде — IMHO не стоит. Мало ли, что там было закоментировано и ко скольким еще левым ошибкам парсинга это приведет. Особенно, если в комментарии будет нечто, влияющее на процесс парсинга (синтаксический макрос, например или там, pragma какая-нибудь). В общем же случае, это сделать стоит, но исключительно в качестве опциональной фичи генерируемых парсеров. Пример языков, где это совершенно точно будет к месту — любое подмножество SGML, например.

Про парсинг в режиме IDE уже сказали выше.

P.S: А если эту фичу можно будет еще и включать/выключать только для определенных правил грамматики — будет совсем здорово (для моих задач )
... << RSDN@Home 1.2.0 alpha 5 rev. 66>>

[Интервью] .NET Security — это просто
Автор: kochetkov.vladimir
Дата: 07.11.17
Re: Восстановление после ошибок парсинга
От: c-smile Канада http://terrainformatica.com
Дата: 01.04.13 06:06
Оценка:
Здравствуйте, VladD2, Вы писали:

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


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


Самое гуманное — показать проблему в месте её возникновения — т.е. там где коментарий открывается.

Иначе получишь JavaScript в котором compiler делает semicolon insertion автоматически.
В результате получается токой вот кунштюк:
return
  a + b;
 
// Returns undefined. Treated as:
//   return;
//     a + b;
Re[2]: Восстановление после ошибок парсинга
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.04.13 09:32
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Самое гуманное — показать проблему в месте её возникновения — т.е. там где коментарий открывается.


Согласен. Сообщение по любому будет на "/*".

CS>Иначе получишь JavaScript в котором compiler делает semicolon insertion автоматически.

CS>В результате получается токой вот кунштюк:
CS>
CS>return
CS>  a + b;
CS>


Да. Смешно. Но это уже область ответственности авторов языка. Мы только предоставляем механизм автоматического восстановления. А в данном случае код корректен.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Восстановление после ошибок парсинга
От: matumba  
Дата: 26.05.13 13:07
Оценка:
Здравствуйте, VladD2, Вы писали:

VD> /*

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

Я всё равно не понял какие ещё могут быть альтернативы. Если коммент не закрыт, парсер должен ткнуть юзера в ОТКРЫВАЮЩИЙ тег и остановиться с ошибкой. Что помимо этого можно придумать??
Re[3]: Восстановление после ошибок парсинга
От: ML380 Земля  
Дата: 26.05.13 13:45
Оценка: 1 (1)
Здравствуйте, VladD2, Вы писали:

VD>Мы можем:

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

VD>2. Выдать сообщение "Обнаружена некорреткная последовательность '/*'" и продолжить парсить код так как будто "/*" не было вовсе.


А второй подход ничего не даст, т.к. за "/*" обычно следует собственно коментарий, парсинг которого приведет к миллиону неиформативных сообщений об ошибках, ковыряться в которох не самое приятное занятие. Т.е. программист все равно исправит отсутствие "*/" и перезапустит компиляцию.
Re[4]: Восстановление после ошибок парсинга
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.05.13 14:48
Оценка:
Здравствуйте, ML380, Вы писали:

ML>А второй подход ничего не даст, т.к. за "/*" обычно следует собственно коментарий, парсинг которого приведет к миллиону неиформативных сообщений об ошибках, ковыряться в которох не самое приятное занятие. Т.е. программист все равно исправит отсутствие "*/" и перезапустит компиляцию.


В некоторых случаях за /* будет вполне корректный код, так как комментарий вписывается в корректный код. Но, согласен, част будет случай когда смысла у идущего следом кода не будет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Восстановление после ошибок парсинга
От: ettcat США  
Дата: 27.05.13 06:23
Оценка:
VD>В некоторых случаях за /* будет вполне корректный код, так как комментарий вписывается в корректный код. Но, согласен, част будет случай когда смысла у идущего следом кода не будет.

Может посмотреть в сторону TagSoup для HTML? Нагородить эвристик что где должно закрываться и выдавать мягкие подсказки. В данном случае компилятор может предположить что комментарий в большинстве случаев закрывается перед определением функции, и если его таки закрыть — то получается валидный код — значит можно выдать не только ошибку, но и подсказку.
Re: Восстановление после ошибок парсинга
От: dmitry_npi Россия  
Дата: 04.06.13 07:52
Оценка:
Здравствуйте, VladD2, Вы писали:


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

То есть, дойдут до конца файла и завершат работу.

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

Но тогда нужен еще один проход?
Атмосферная музыка — www.aventuel.net
Re: Восстановление после ошибок парсинга
От: Воронков Василий Россия  
Дата: 04.06.13 10:41
Оценка:
Здравствуйте, VladD2, Вы писали:

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

VD>Но в принципе тут можно восстановиться записав "/*" в грязь (т.е. проигнорировать начало комментария).
VD>Какой вариант по вашему лучше? И какие подводные грабли тут могут возникнуть?

Для именно данной конкретной ошибки дополнительные эвристики особо не нужны, т.к. не сильно помогут. Подсветка кода тебе и так сразу покажет, что у тебя не так. Если же пытаться игнорировать /* и компилировать все, что после него, то, скорее всего, дело закончится кучей ошибок, которые возникнут при попытке скомпилировать комментарии. Зачем?

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

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

_>Но тогда нужен еще один проход?

Нет. Не нужен. Просто чуть-чуть иной алгоритм. Когда мы доходим до этого места, то парсер падает на всех имеющихся правилах. Далее мы тупо пропускаем по одному символу и пытаемся парситься дальше. После пропуска двух символов мы встречаем разумное продолжение и продолжаем парсинг. В итогде /* записываются в мусор и как бы игнорируются парсером.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Восстановление после ошибок парсинга
От: TimurSPB Интернет  
Дата: 05.06.13 10:21
Оценка:
VD>Какой вариант по вашему лучше? И какие подводные грабли тут могут возникнуть?
В описании синтаксиса языка комментарии должны быть закрыты. А компилятор должен соответствовать описанию. Так что надо выдавать ошибку.
В идеале, он должен сообщить в ошибке не только что ждет в конце файла закрытия комментария. Хорошо бы дополнить сообщением местом, где он открыт.
Make flame.politics Great Again!
Re: Восстановление после ошибок парсинга
От: Философ Ад http://vk.com/id10256428
Дата: 17.06.13 11:35
Оценка:
Здравствуйте, VladD2, Вы писали:


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


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


компилер должен ткнуть в открывающий комментарий и остальное не парсить.
в случае IDE, всё, что после начала комментария распознавать как комментарий
Всё сказанное выше — личное мнение, если не указано обратное.
Re: Восстановление после ошибок парсинга
От: seregaa Ниоткуда http://blogtani.ru
Дата: 24.06.13 18:32
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Всем привет.


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


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


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


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


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


Означает ли первый вариант реализации, что после незакрытого комментария сломается расцветка кода и автокомплит? Если это относится только к незакрытому комментарию, то фиг с ним, пусть ломается — так даже проще будет найти строчку с ошибкой. Но если автокомплит будет ломаться после любой строчки с недописанным кодом, то мне будет неудобно. Поэтому наверное стоит рассмотреть как можно больше конкретных ситуаций и выбрать поведение для каждого из них.
Мобильная версия сайта RSDN — http://rsdn.org/forum/rsdn/6938747
Автор: sergeya
Дата: 19.10.17
Re[2]: Восстановление после ошибок парсинга
От: Кодт Россия  
Дата: 28.06.13 22:07
Оценка: +1
Здравствуйте, MTD, Вы писали:

MTD>Мне — человеку, проще чтобы меня ткнули носом в незакрытый комментарий, чем выдали 100 наведенных ошибок из которых мне самому пришлось бы делать вывод, что нужно сделать.


У турбо-паскаля было именно такое поведение: тыкал носом в первую встреченную ошибку, а не выдавал 100 наведённых.
Офигительно "удобно", сто попыток перекомпиляции, пока каждую ошибку не исправишь.
Перекуём баги на фичи!
Re[2]: Восстановление после ошибок парсинга
От: Кодт Россия  
Дата: 28.06.13 22:08
Оценка:
Здравствуйте, TimurSPB, Вы писали:

TSP>В описании синтаксиса языка комментарии должны быть закрыты. А компилятор должен соответствовать описанию. Так что надо выдавать ошибку.


Он её и выдаст, в виде exitcode 1, так что билд-система (make, vcbuid, ant, etc.) остановятся.
Но это интерфейс к билд-системе. А речь идёт об интерфейсе к человеку.
Перекуём баги на фичи!
Re[3]: Восстановление после ошибок парсинга
От: Кодт Россия  
Дата: 28.06.13 22:26
Оценка: 20 (1)
Здравствуйте, VladD2, Вы писали:

VD>Нет. Не нужен. Просто чуть-чуть иной алгоритм. Когда мы доходим до этого места, то парсер падает на всех имеющихся правилах. Далее мы тупо пропускаем по одному символу и пытаемся парситься дальше. После пропуска двух символов мы встречаем разумное продолжение и продолжаем парсинг. В итогде /* записываются в мусор и как бы игнорируются парсером.


Я вот подумал: а нельзя ли сюда приплести какую-нибудь недетерминированную систему (скрытую марковскую модель там...)
Это будет не совсем "тупо пропускаем по символу", а, например, так.

Рассмотрим n-граммы лексем или даже термов, и их вероятности.
Вероятность /* всякая фигня, ломающая лексер высоко вероятна; /* something() breaking parser тоже вероятно; /* {good();code(); сравнимо с обычным кодом.

Как только парсер или лексер споткнулся, прекращаем детерминированное чтение и начинаем недетерминированное, выбирая, я уж не знаю, 100 лучших гипотез на каждую лексему. В недетерминированном должны встречаться эпсилон-переходы, то есть, мысленное дописывание забытых лексем (закрывающих */, например) и мысленное вычёркивание лишних.
Пройдя достаточно длинный отрезок текста, выбираем наилучшую гипотезу и парсим её.

Эвристический подход состоит в разбиении текста по характерным местам для восстановления: это ';' и '}', а также EOF (лечимся от кривых инклудов) и пробельные строки (здравый смысл подсказывает).
Тем самым мы занимаемся догадками (как выше) или восстанавливаем контекст (как ты предложил) не слишком мелочно и не слишком далеко по тексту.

Для интеллисенса должно помочь.
Перекуём баги на фичи!
Re[3]: Восстановление после ошибок парсинга
От: hattab  
Дата: 28.06.13 22:40
Оценка:
Здравствуйте, Кодт, Вы писали:

К> У турбо-паскаля было именно такое поведение: тыкал носом в первую встреченную ошибку, а не выдавал 100 наведённых.

К> Офигительно "удобно", сто попыток перекомпиляции, пока каждую ошибку не исправишь.

С его-то скоростью компиляции — не проблема вообще.
avalon 1.0rc3 build 432, zlib 1.2.5
Re[4]: Восстановление после ошибок парсинга
От: Кодт Россия  
Дата: 28.06.13 23:31
Оценка:
Здравствуйте, hattab, Вы писали:

H>С его-то скоростью компиляции — не проблема вообще.


Ещё какая проблема. Ты использовал паскаль для промышленного программирования, а не школьно-институтского? Я использовал. Бесит — это ничего не сказать.
Перекуём баги на фичи!
Re[5]: Восстановление после ошибок парсинга
От: hattab  
Дата: 29.06.13 05:54
Оценка:
Здравствуйте, Кодт, Вы писали:

К> H>С его-то скоростью компиляции — не проблема вообще.


К> Ещё какая проблема. Ты использовал паскаль для промышленного программирования, а не школьно-институтского? Я использовал. Бесит — это ничего не сказать.


Я его использую. Не турбо-паскаль конечно. В дельфях Ctrl+F9 (Compilation) можно рассматривать как хоткей для перехода на следующую ошибку — зверски быстро
avalon 1.0rc3 build 432, zlib 1.2.5
Re[6]: Восстановление после ошибок парсинга
От: Кодт Россия  
Дата: 29.06.13 08:55
Оценка:
Здравствуйте, hattab, Вы писали:

H>Я его использую. Не турбо-паскаль конечно. В дельфях Ctrl+F9 (Compilation) можно рассматривать как хоткей для перехода на следующую ошибку — зверски быстро


Нда... а я надеялся, что хоть потомки будут жить при коммунизме, и в дельфях этой фичи не будет.
Вообще, странно, что именно в паскале с его простым синтаксисом не смогли сделать такой предсказатель.
Перекуём баги на фичи!
Re[7]: Восстановление после ошибок парсинга
От: hattab  
Дата: 29.06.13 09:27
Оценка: 2 (1)
Здравствуйте, Кодт, Вы писали:

К> H>Я его использую. Не турбо-паскаль конечно. В дельфях Ctrl+F9 (Compilation) можно рассматривать как хоткей для перехода на следующую ошибку — зверски быстро


К> Нда... а я надеялся, что хоть потомки будут жить при коммунизме, и в дельфях этой фичи не будет.

К> Вообще, странно, что именно в паскале с его простым синтаксисом не смогли сделать такой предсказатель.

Сделали. Но Ctrl+F9 использовать сильно проще
avalon 1.0rc3 build 432, zlib 1.2.5
Re: Восстановление после ошибок парсинга
От: nikov США http://www.linkedin.com/in/nikov
Дата: 22.07.13 17:26
Оценка: +1
Здравствуйте, VladD2, Вы писали:

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

VD>Но в принципе тут можно восстановиться записав "/*" в грязь (т.е. проигнорировать начало комментария).
VD>Какой вариант по вашему лучше? И какие подводные грабли тут могут возникнуть?

В идеале, надо предполагать, что отсутствующий токен */ находится в такой позиции, которая ведёт к наименьшему количеству ошибок в проекте. Предчувствую, что это непросто реализовать
Re[2]: Восстановление после ошибок парсинга
От: VladD2 Российская Империя www.nemerle.org
Дата: 22.07.13 19:14
Оценка:
Здравствуйте, nikov, Вы писали:

N>В идеале, надо предполагать, что отсутствующий токен */ находится в такой позиции, которая ведёт к наименьшему количеству ошибок в проекте. Предчувствую, что это непросто реализовать


Ага. Экспонента вылезает.

Мы уже угаждываем продолжение не хуже ИИ . Но в идеале нужно тупо перебирать все варианты продолжения и пытаться опарсить хвост в штатном решжие. Тут появляются ветвления. А в них свои ветвления...
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Восстановление после ошибок парсинга
От: alpha21264 СССР  
Дата: 22.07.13 19:47
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Ага. Экспонента вылезает.


VD>Мы уже угаждываем продолжение не хуже ИИ . Но в идеале нужно тупо перебирать все варианты продолжения и пытаться опарсить хвост в штатном решжие. Тут появляются ветвления. А в них свои ветвления...


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

По моему, не так страшно. Потренироваться можно на кошках.
То есть, поиграть на файле, который содержит только комментарии

К стати, почему мы говорим "синтаксическое дерево",
хотя это сначала это "синтаксический список"
и только потом он становится деревом?

Течёт вода Кубань-реки куда велят большевики.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.