Каковы некоторые подходы для сбора и передачи ошибок компилятора

#.net #compiler-construction #f# #functional-programming #compiler-errors

#.net #компилятор-конструкция #f# #функциональное программирование #ошибки компилятора

Вопрос:

Самый простой подход — просто выдать исключение с информацией об ошибке при первом возникновении ошибки. Возможно, другой подход заключается в передаче изменяемого аргумента списка через функции анализа. Но я заметил, что, например, компилятор F # будет постепенно накапливать ошибки на панели ошибок Visual Studio на протяжении всей компиляции. Можно ли использовать TraceListener? Каковы некоторые плюсы и минусы различных подходов.

Меня особенно интересуют подходы к таргетингу компиляторов.NET использует функциональный язык, такой как F #, но был бы признателен за подходы (которые могут отличаться или не отличаться) и в других контекстах.

Ответ №1:

Вы всегда можете посмотреть на код компилятора F # в качестве одного примера (хотя реальный код всегда немного запутан :)):

https://github.com/fsharp/fsharp/blob/master/src/fsharp/ErrorLogger.fs

У нас есть интерфейс ErrorLogger с предупреждениями и «приемниками» ошибок, а также различные части компилятора «передают» ошибки и предупреждения активному регистратору через интерфейс.

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

Как кто-то сказал, компиляторы универсально записывают выходные данные в стандартный вывод / stderr в каноническом формате. MSBuild и Visual Studio анализируют выходные данные сборки, чтобы отобразить список ошибок и закорючки в интерфейсе IDE. Для дополнительной обратной связи при наборе текста (а не при сборке) VS также «размещает» интерфейс компилятора в процессе и считывает сообщения об ошибках непосредственно из «приемников».

Пока у вас есть хотя бы одна граница абстракции (например, a LogWarning и LogError function , которая может быть даже глобальной, просто убедитесь, что все предупреждения / ошибки используют ее), тогда вы всегда сможете провести рефакторинг в соответствии с меняющимися потребностями / проектами.

Комментарии:

1. Спасибо @Brian! Я без особого энтузиазма взглянул на код компилятора F #, но мне действительно нужно было подобное объяснение, чтобы привести мое понимание.

Ответ №2:

Любой компилятор, который я использовал, в том числе .ЧИСТЫЕ, немедленно выводят сообщение об ошибке на консоль. Довольно важным соображением является то, что это позволяет программисту вводить Ctrl C, чтобы быстро положить конец множеству ошибок, которые генерируются из-за ошибки в объявлении. В наши дни это уже не очень актуально, но ни один из них не делает это по-другому.

Комментарии:

1. Верно, и я хотел бы предоставить тот же опыт для консольной версии компилятора, но я предполагаю, что с точки зрения реализации большинство компиляторов не записывают данные непосредственно на консоль при возникновении ошибок, скорее используется какой-то промежуточный механизм, позволяющий гибко подключать компилятор к IDE, среде REPLили предоставляется как сервис.

2. Компиляторы универсально реализованы как инструменты командной строки в Windows. Они записывают непосредственно на консоль, их вывод просто перенаправляется. Важно поддерживать среды сборки, отличные от IDE.