Я размещал это в группе новостей D несколько месяцев назад, но по какой-то причине ответ никогда меня не убедил, поэтому я подумал, что попрошу его здесь.
Грамматика D, по-видимому, контекстно-зависимая.
Однако грамматика С++ не существует (даже без макросов). (Пожалуйста, внимательно прочитайте это!)
Теперь предоставлено Я ничего не знаю (официально) о компиляторах, лексерах и парсерах. Все, что я знаю, это то, что я узнал в Интернете.
И вот что (я считаю) я понял относительно контекста, в не-техническом жаргоне:
Грамматика языка является контекстно-свободным тогда и только тогда, когда вы всегда можете понять смысл (хотя и не обязательно точное поведение) данного фрагмента своего кода, не нуждаясь в том, чтобы "смотреть" где-нибудь еще.
Или в еще меньшей степени:
Грамматика не может быть контекстной, если мне нужно, я не могу сказать тип выражения, просто посмотрев на него.
Итак, например, С++ терпит неудачу в контексте без проверки, потому что значение confusing<sizeof(x)>::q < 3 > (2)
зависит от значения q
.
До сих пор так хорошо.
Теперь мой вопрос: можно ли сказать одно и то же о D?
В D хэш-таблицы могут быть созданы с помощью объявления Value[Key]
, например
int[string] peoplesAges; // Maps names to ages
Статические массивы могут быть определены в аналогичном синтаксисе:
int[3] ages; // Array of 3 elements
И шаблоны могут использоваться для их запутывания:
template Test1(T...)
{
alias int[T[0]] Test;
}
template Test2(U...)
{
alias int[U] Test2; // LGTM
}
Test1!(5) foo;
Test1!(int) bar;
Test2!(int) baz; // Guess what? It invalid code.
Это означает, что я не может определить значение T[0]
или U
, просто посмотрев на него (т.е. это может быть число, это может быть тип данных, или это может быть кортеж Бога-знает-что). Я даже не могу сказать, является ли выражение грамматически корректным (поскольку int[U]
, конечно же, нет - вы не можете иметь хэш-таблицу с кортежами в качестве ключей или значений).
Любое дерево разбора, которое я пытаюсь сделать для Test
, не будет иметь никакого смысла (поскольку ему нужно знать, содержит ли node тип данных по сравнению с литералом или идентификатором), если он не задерживает результат до тех пор, пока значение T
известно (что делает его зависимым от контекста).
Учитывая это, D действительно контекстно-свободный, или я не понимаю понятие?
Почему/почему нет?
Обновление:
Я просто подумал, что буду комментировать: Мне действительно интересно увидеть ответы, поскольку:
- В некоторых ответах утверждается, что С++ и D не могут быть контекстно-зависимыми
- Некоторые ответы утверждают, что С++ и D являются контекстно-свободными
- Некоторые ответы подтверждают утверждение, что С++ является контекстно-зависимым, а D не является
- Никто еще не утверждал, что С++ не имеет контекста, в то время как D является контекстно-зависимым: -)
Я не могу сказать, учился ли я или становился все более смущенным, но в любом случае, я рад, что я спросил об этом... спасибо, что нашли время, чтобы ответить, всем!