Как обычно комментируются комментарии?
Как комментарии, как правило, обрабатываются на языках программирования и разметке? Я пишу парсер для некоторых пользовательских языков разметки и хочу следовать принципу наименьшего удивления , поэтому я пытаюсь определить общее соглашение.
Например, должен ли комментарий, встроенный в токен, «вмешиваться» в токен или нет? Как правило, это что-то вроде:
Sys/* comment */tem.out.println()
действует?
Кроме того, если язык чувствителен к новым строкам, а комментарий охватывает новую строку, следует ли рассматривать новую строку или нет?
stuff stuff /* this is comment
this is still comment */more stuff
следует рассматривать как
stuff stuff more stuff
или
stuff stuff
more stuff
?
Я знаю, что делают некоторые конкретные языки, и я не ищу мнения, но я ищу, есть ли общий консенсус в отношении того, что обычно ожидается с помощью маркировки в отношении токенов и новых строк?
Мой конкретный контекст является вики-подобной разметкой.
5 ответов
Обычно комментарии сканируются (и отбрасываются) как часть процесса токенизации, но до разбора. Комментарий работает как разделитель токенов даже в отсутствие пробелов вокруг него.
Как вы отмечаете, спецификация C явно заявляет, что комментарии заменяются одним пробелом. Это всего лишь спецификация-лингво, поскольку, поскольку симулятор реального мира фактически ничего не заменит, он просто сканирует и отбрасывает комментарий так же, как он сканирует и отбрасывает пробельные символы. Но это объясняет простым образом, что комментарий разделяет токены так же, как и пространство.
Содержание комментариев игнорируется, поэтому разрывы строк внутри многострочных комментариев не влияют. Языки, которые чувствительны к разрыву строк (Python и Visual Basic), обычно не имеют многострочных комментариев, но одним исключением является JavaScript. Например:
return /*
*/ 17
Является эквивалентным
return 17
не
return
17
Одиночные комментарии сохраняют разрыв строки, т. е.
return // single line comment
17
эквивалентно
return
17
не
return 17
Поскольку комментарии сканируются, но не анализируются, они, как правило, не гнездятся. Так
/* /* nested comment */ */
является синтаксической ошибкой, так как комментарий открывается первым /*
и закрывается первым */
Чтобы ответить на вопрос:
существует ли общий консенсус, что обычно ожидается с помощью метки?
Я бы сказал, что никто не ожидал, что комментарий, встроенный внутри токена, будет легальным.
Как правило, комментарии следует рассматривать так же, как пробелы. Любое место, которое было бы действительным, чтобы иметь посторонние пробелы, также должно иметь встроенный комментарий. Единственным исключением могут быть строки:
trace("Hello /*world*/") // should print Hello /*world*/
Было бы довольно странно поддерживать комментарии внутри строк и ускользнуть от них утомительно!
В языках с незащищенными пробелами игнорируемые символы (т. е. пробелы или те, которые являются частью комментария) ограничивают токены.
Итак, например Sys tem
- два токена, а System
- один. Полезность этого может быть более очевидной, если вы сравните new Foo()
и newFoo()
, один из которых построит экземпляр Foo
, в то время как другие вызовы newFoo
Комментарии могут играть ту же роль, что и пробег пробелов, например. new/**/Foo()
работает так же, как new Foo()
. Конечно, это может быть более сложным, например. new /**/ /**/ Foo()
или еще что-то.
Технически, должно быть возможно разрешить комментарии внутри идентификаторов, но я сомневаюсь, что это особенно практично.
Теперь, что из чувствительных к белому пространству языков?
Python приходит на ум, и он имеет очень простой ответ: никаких комментариев блока. Вы начинаете комментарий с помощью #
, а затем парсер работает точно так же, как если бы остальная часть строки не существовала, а была просто новой линией .
В отличие от этого, jade разрешает комментарии к блоку , где заканчивается блок, когда вы возвращаетесь к тому же уровень отступов. Пример:
body
//-
As much text as you want
can go here.
p this is no longer part of the comment
Итак, в этой области я бы не сказал, что вы могли бы сказать, как делаются обычно . То, что кажется общности, состоит в том, что комментарий всегда заканчивается окончанием строки, что означает, что все комментарии действуют точно так же, как новые строки.
В прошлом я превратил комментарии в один токен как часть лексического анализа. То же самое касается строк. Оттуда жизнь легко.
В конкретном случае последнего синтаксического анализатора, который я построил, правило исключения передается в процедуру анализа синтаксиса верхнего уровня. Правило escape используется для обработки токенов, таких как токены комментариев, встроенные в основную грамматику. В общем, эти жетоны были отброшены.
Следствием этого является то, что в примере, который вы отправили с комментарием в середине идентификатора, идентификатор не был бы единственным идентификатором - это ожидаемое поведение на всех языках (из памяти) ve работал с.
Случай комментария в строке должен быть неявно обработан лексическим анализом. Правила обработки строки не интересуются комментариями, и поэтому комментарий рассматривается как содержимое строки. То же самое относится к строке (или цитируемому литералу) в комментарии - строка является частью комментария, которая явно является единственным токеном; правила обработки комментария не интересуются строками.
Я надеюсь, что это имеет смысл /помогает.
Это зависит от того, в чем состоит ваш парсер. Если вы пишете синтаксический анализатор для построения дерева синтаксического анализа для компиляции, то комментарий не имеет семантического значения, помимо потенциального разделения токенов (например, method / comment /(/ comment /)). В этом случае его обработанные подобные пространства.
Если ваш парсер является частью транспилятора, переводящего один исходный язык на другой исходный язык, или если ваш синтаксический анализатор является препроцессором, принимающим блок компиляции на исходном языке, анализируя его, изменяя его и записывая измененную версию обратно в том же источнике язык, комментарии, как и все остальное, становятся очень важными.
Также, если у вас есть метаинформация в комментариях, и вы особенно заботитесь о комментариях, например, при создании API-документации, такой как JavaDoc, комментарии очень важны.
Здесь комментарии часто привязаны к самим токенам. Если вы найдете комментарий, вы присоедините его к комментарию к токену. Поскольку токен может иметь несколько токенов до и после, он снова зависит от цели, как обрабатывать эти комментарии.
Идея аннотации токенов без комментариев с комментариями заключается в том, чтобы вообще удалить комментарии из грамматики.
После того, как у вас есть дерево разбора, некоторые AST начинают распаковывать комментарии, представляющие каждый токен, своим собственным AST-Element, но прикрепляются к другому AST-Element наряду с обычными сословными отношениями. Хорошая идея - проверить все реализации парсера /АСТ для исходных языков, доступных в среде с открытым исходным кодом.
Одна очень хорошая реализация - это инфраструктура компилятора Eclipse для языка Java. Они сохраняют комментарии во время токенизации и представляют комментарии в АСТ - насколько я помню. Кроме того, реализация этого анализатора /AST сохраняет форматирование.