LINUX.ORG.RU

Грамматики ЯП по Хомскому.

 


2

4

Пытаюсь рзобраться сейчас с сабжем, в частности с грамматикой TCL. И на обном из сайтов столкнулся вот с таким: " Tcl не является языком, который можно описать статической грамматикой. Он относится к классу так называемых контекстно-зависимых языков, для которых традиционными (основанными на формах Бэкуса-Наура и их модификациях) грамматиками «распознавание» всех возможных формально правильных предложений принципиально неосуществимо. Донэл Феллоуз (Donal Fellows) об этой отличительной черте Tcl высказал следующее мнение: формально правильные Tcl-предложения не могут быть распознаны никаким иным вычислителем, кроме машины Тьюринга. "

Источник: http://itc.ua/articles/drevnyaya_novaya_budushhaya_prodolzhenie_16346/

Это выдается там, вроде, за фичу тикля, но на другом сайте встретил:

context-sensitive languages — most programming languages

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


Ответ на: комментарий от qulinxao

Да, и еще добавлю, нету никакого «терминатор_команды», границы команд определяются парсером по своей КС-грамматике.

anonymous
()
Ответ на: комментарий от anonymous

ок, тикль оказался не так безбашен как форт, хвала тиклю.

qulinxao ★★☆
()
Ответ на: комментарий от emulek

а зачем ты их строил?

Чтобы распечатать. Чтобы проверить синтаксическую корректность программы. Или я просто научился писать парсеры, а на полноценную компиляцию сил еще не хватает.

(+ b a)

Зачем ты перепутал местами операнды? У бинарного оператора есть левый и правый операнды, с чего это левому становиться правым и наоборот?

staseg ★★★★★
()
Ответ на: комментарий от MKuznetsov

С и С++ полностью и исчерпывающе описываются внешней формальной грамматикой. Если некий текст строго соответсвует формальной грамматике С/С++ - то он 100% является программой на С/C++. То есть С/С++ контекстно свободны.

какое у вас интересное определение, прям прорыв в отечественном CS.

RedPossum ★★★★★
()
Ответ на: комментарий от anonymous

ну да, скорее есть «апликативный» порядок подготовки аргументов в тикле в отличии от форта/лиспа где есть категория_команд(немедленые в форте и «спец_формы»|макросы в лиспе) для которых «нормальный» порядок.

т.е для тикля синтаксис более жёсток.

qulinxao ★★☆
()
Ответ на: комментарий от qulinxao

значит ли это, что в первой цитате стартового топика ошибка?

Tcl не является языком, который можно описать статической грамматикой.

Ведь если, как пишет анон

границы команд определяются парсером по своей КС-грамматике.

значит он все таки описывается КС-грамматикой? Или как?

new_1
() автор топика
Ответ на: комментарий от qulinxao

команда море_ада_в_котором_запускают_..._и_играют_в_крестики_нолики терминатор_команды.

где команда ранее обьявленая команда которой фиксированный тикл_парсер передаёт её аргументТМ с которым команда и своим окружением(контекстом исполнения) может сотворить что угодно.

IRL в Tcl «команда» может быть не объявлена, терминатора в явном виде может не быть.

С точки зрения «внутреннего устройства» интерпретатора Tcl, единственно нужно чтоб ему была техническая возможность сформировать конечный вектор(Tcl_Obj *) из входящих токенов. При этом есть случаи когда даже скобки (){}[] с кавычками «» могут быть не сбалансированы. :)

ещё чуть - и станет возможен легальный доступ к текущему токенайзеру, тогда даже собственные границы команда сможет определять сама :-) Теоретически такой патч возможен и даже не слишком будет велик, но только Tcl`ю вряд ли это нужно - только путаницы добавит

MKuznetsov ★★★★★
()
Ответ на: комментарий от anonymous

Да, и еще добавлю, нету никакого «терминатор_команды», границы команд определяются парсером по своей КС-грамматике.

Да? Ну и как же парсер определяет границы команды если синтаксис нетерминирован? Вы умники, уже сами себя, мля, перемудрили. Это что-то навроде

foo bar baz
Парсер:

может код состоит из fo o bar baz
может код состоит из foo bar baz
остановлюсь ка я где-нибудь, ведьпо*йвсе, терминатора команды немая.

anonymous
()
Ответ на: комментарий от anonymous

Да? Ну и как же парсер определяет границы команды если синтаксис нетерминирован? Вы умники, уже сами себя, мля, перемудрили. Это что-то навроде

Синтаксис как раз детерминирован. Имелось ввиду, что нет никакого кустомного «терминатора команды», который «команда» может переопределить для себя. А в синтаксисе TCL разделителями команд являются перевод строки и точка с запятой.

anonymous
()
Ответ на: комментарий от staseg

Чтобы распечатать. Чтобы проверить синтаксическую корректность программы. Или я просто научился писать парсеры, а на полноценную компиляцию сил еще не хватает.

а... Ну это другой вопрос.

Зачем ты перепутал местами операнды? У бинарного оператора есть левый и правый операнды, с чего это левому становиться правым и наоборот?

такой вот синтаксис у C/C++. Т.е. синтаксически a+b можно читать как a+b и ОДНОВРЕМЕННО можно читать как b+a. Т.е. проще говоря, порядок операндов НЕ ОПРЕДЕЛЁН. И говорить «левый»/«правый» == делить на ноль.

Да, я знаю, что в арифметике порядок не имеет значения, вот только в сишечке своя арифметика.

Да, вот ещё пример: дано a=3, b=4, вопрос: a+b=?. Как не странно, ответ зависит от синтаксического контекста, если a это указатель на int, то ответ 3+4*4=19.

emulek
()
Ответ на: комментарий от new_1

значит он все таки описывается КС-грамматикой? Или как?

На лексическом уровне - наверное можно сказать, что КС. С другой стороны, обычно грамматики определяют синтаксис, больше статических гарантий. А тут, встретив «while» - не понятно, команда или пользовательская процедура.

anonymous
()
Ответ на: комментарий от emulek

проще говоря, порядок операндов НЕ ОПРЕДЕЛЁН. И говорить «левый»/«правый» == делить на ноль

Вбросил, понял - что полный фейл, испугался, пытается прикрыть газеткой.

anonymous
()
Ответ на: комментарий от emulek

такой вот синтаксис у C/C++. Т.е. синтаксически a+b можно читать как a+b и ОДНОВРЕМЕННО можно читать как b+a. Т.е. проще говоря, порядок операндов НЕ ОПРЕДЕЛЁН. И говорить «левый»/«правый» == делить на ноль.

Все смешалось. В голове. Как раз синтаксически a+b читается только как a+b. А в каком порядке вычислять значения операндов или в каком порядке применять к ним функцию-операнд, решает семантика. Если семантику не определяет стандарт языка, ее определит компилятор. А синтаксическое дерево он построит единственно верное и не будет каким-то магическим образом выбирать одно из нескольких.

Да, вот ещё пример: дано a=3, b=4, вопрос: a+b=?.

Мне без разницы результат вычислений. Синтаксически программа корректна.

Короче. В этом треде уже человек пять ткнула тебя в неправоту, некоторые даже пытаются объяснить. Ты можешь думать, что один самый умный. Или взять в зубы литературу, коей предостаточно на данную тему, и изучить вопрос. В любом случае довольно глупо спорить о том, в чем нифига не разбираешься. Как бы знание С++ еще не дает права рассуждать о структуре языков.

staseg ★★★★★
()
Ответ на: комментарий от staseg

Эмулек конечно некомпетентная макака, но a + b может разобраться и в (+ b a), если мы так определим синтаксические правила разбора. Не в C/C++, конечно.

aedeph_ ★★
()
Ответ на: комментарий от aedeph_

Ты конечно, о-о-очень компетентная макака, но ты говоришь о преобразовании, а речь, если ты заметил, о грамматике. «Разобраться в...» с точки зрения макаки — валидное выражение, но смысла оно не имеет.

anonymous
()
Ответ на: комментарий от aedeph_

грамматики, деревья, танчики, линейки

Да, мудачок, для овец вроде тебя все одно. Главное — побольше неоднозначных, шоб никто не понял.

anonymous
()

Да, похоже, ошибка во втором утверждении. Обычно считается, что большинство - контекстно-свободные. Например в википедии:

Для языка, который описывается контекстно-свободной грамматикой, какими являются почти все языки программирования, создание абстрактного дерева...

Может быть раньше было так, хз.

selena-gomes
()

Это выдается там, вроде, за фичу тикля

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

Особенность тикля в том, что команды могут сами интерпретировать свои параметры, а значит смысл выражений передаваемых команде зависит от самой команды. Т.е., например смысл выражений 2+2 или a,b зависит от того, какой команде они передаются.

no-such-file ★★★★★
()
Ответ на: комментарий от anonymous

шоб никто не понял.

То есть ты не знаешь, что означают данные термины и как они связаны с тем, что я написал до этого, при этом имеешь наглость что-то брякать?

Аноним совсем дегенеративный пошёл, почти на уровне Баттяни.

aedeph_ ★★
()
Ответ на: комментарий от no-such-file

Дело не в «означать». То, что ты оперируешь словом «означать», показывает, что ты не понимаешь, что такое формальная грамматика по Хомскому. Грамматика имеет отношение ТОЛЬКО к синтаксису. А точнее, классы грамматики соответствуют различным классам конечных автоматов, которыми можно определить, является ли входная последовательность допустимой для указанной грамматики.

Вот пример контекстно-зависимой грамматики:

L :: {десятичное число N} {пробел} {N произвольных символов}

Такую грамматику невозможно распознать при помощи контекстно-свободного автомата (например, LR-парсера).

anonymous
()
Ответ на: комментарий от aedeph_

А ну ша! Аноним лишь отражает ваше собственное коллективное бессзознательное, лол.

anonymous
()
Ответ на: комментарий от staseg

Все смешалось. В голове. Как раз синтаксически a+b читается только как a+b.

синтаксически в сишке это читается как _сумма_. И не более того. Просто у нас нет такого значка, что-бы указать на то, что это и a+b и b+a, причём выбор от синтаксиса не зависит, тут ты прав. Прав ты и в том, что результат к синтаксису не имеет отношения. А ошибаешься как раз потому, что при суммировании int результат не меняется. Потому в итоге разный синтаксический разбор даёт одинаковый результат. В выражении a÷b ты же не будешь спорить, что b это делитель? А не a? Чисто по синтаксису.

a+b

Мне без разницы результат вычислений. Синтаксически программа корректна.

она даже синтаксически не корректна, если a и b это указатели. Ибо по синтаксис сложения указателей в C/C++ не определён.

В любом случае довольно глупо спорить о том, в чем нифига не разбираешься. Как бы знание С++ еще не дает права рассуждать о структуре языков.

ну-ну...

emulek
()
Ответ на: комментарий от selena-gomes

тут путаница яп как целого(какие «слова» валидны и что это «слово» значит) и этап проверки синтаксиса - который легко отсекает заведо ложное из универсума.

любое обьявление имени как переменой(чего угодно) - в языке где нет возможности спонтанного именнования(не помнию как это называется когда обьявления не нужны ) по определению есть контекст.

до этапа же связывания «имён» есть критерии .

qulinxao ★★☆
()
Ответ на: комментарий от anonymous

То, что ты оперируешь словом «означать», показывает, что ты не понимаешь, что такое формальная грамматика по Хомскому

Мне лениво разводить тут курс математической грамотности, но вообще, для ТС достаточно и объяснения «на пальцах».

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

Мне лениво разводить тут курс математической грамотности, но вообще, для ТС достаточно и объяснения «на пальцах».

Так твоё объяснение получается про то, почему трава зелёная, а ТС спрашивал, почему подушка мягкая. Он конечно криво вопрос задал, но это не значит, что надо отвечать невпопад.

Разница между различными видами запятых в Си как раз является контекстно-свободной, так что твой пример ошибочен.

anonymous
()
Ответ на: комментарий от anonymous

Уточню:

Разница между различными видами запятых в Си как раз является контекстно-свободной

При условии, если бы грамматика Си в целом была контекстно-свободной. А это не так. Но зависимость от контекста там совсем не в запятых.

anonymous
()
Ответ на: комментарий от anonymous

а ТС спрашивал, почему подушка мягкая

ТС спрашивал именно о том, что я ответил. Тут же нафлудили уже хз сколько страниц про сферических коней.

no-such-file ★★★★★
()
Ответ на: комментарий от anonymous

Но зависимость от контекста там совсем не в запятых

А что в твоём понимании контекст? Я всегда считал, что это последовательность окружающих символов.

Тогда foo(1,2,3) - контекст foo( ), 8+1,2,3+9 - контекст 8+ +9. Запятые трансформируются в разные AST? Значит запятая -контекстно зависимая, или как?

no-such-file ★★★★★
()
Ответ на: комментарий от aedeph_

ты не знаешь

Нет, я знаю, в том числе и то, то ты них*я не понимаешь о чем ты лепечешь.

означают данные термины

Термины есть, но другие. Есть грамматика, и есть синтаксический анализ (деревья и все-все-все), что не одно и то же, а про

Неоднозначные грамматики

lol, я в следующий раз у бабки на рынке спрошу, и тоже буду знать, ты ведь у нее спрашивал?

anonymous
()
Ответ на: комментарий от no-such-file

А что в твоём понимании контекст? Я всегда считал, что это последовательность окружающих символов.

Да. Последовательность окружающих символов или любые алгоритмические «выводы», которые можно сделать из этих символов.

Однако, обрати внимание, что зависимость выбора от вышележащего нетерминала НЕ является зависимостью от контекста. КС-автоматы как раз и оперируют распознаванием вложенных нетерминалов, для них это не «окружающие символы», а просто стек нетерминалов от корня до текущего.

Вот пример контекстной зависимости в Си:

int a, b;
void f()
{
    a * b;
}
typedef int a;
void f()
{
    a * b;
}

КС-автомат не сможет узнать, в какой нетерминал нужно свернуть последовательность a * b: в expression или в declaration. Чтобы принять решение, нужен доступ к контексту.

Вышелележащие нетерминалы в обоих случаях одинаковы, а выбор надо сделать разный.

Поэтому грамматика Си контекстно-зависима.

С запятыми ситуация иная:

f(x, y, z);
x, y, z;

В первом случае запятая парсится в рамках нетерминала argument_list, а во втором в рамках нетерминала expression.

Здесь нет зависимости от контекста: парсер знает, в какой нетерминал он свёрнёт последовательность.

anonymous
()
Ответ на: комментарий от anonymous

У тебя программа упадет, если ты будешь складывать указатели?

у меня ошибка в синтаксисе. Программа даже не соберётся:

arrays.c: В функции «main»:
arrays.c:29:12: ошибка: invalid operands to binary + (have «int *» and «int *»)
  int *c = a+b;
            ^

emulek
()
Ответ на: комментарий от emulek

Ну тогда о какой контекстозависимости ты говоришь? Контекстозависимость была бы, если бы твоя операция умножения умела работать с разными контекстами, т.е. операция зависела от контекста применения (в данном случае - аргументов, их типа). У тебя здесь контекстно-свободная грамматика, поэтому компилятор однозначно определяет ошибку.

anonymous
()
Ответ на: комментарий от anonymous

В первом случае запятая парсится в рамках нетерминала argument_list, а во втором в рамках нетерминала expression.

Но парсится-то она по-разному. Так и в вашем примере можно сказать, что всё выражение парсится в рамках нетерминала translation_unit, т.е. вся единица трансляции - нетерминал.

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

А что в твоём понимании контекст? Я всегда считал, что это последовательность окружающих символов.

в C/C++ не только и не столько. Смысл выражения определяется не только окружающими символами, но и определениями, которые могут быть в любом месте ДО этого. IRL часто они закопаны глубоко в #include.

Т.е. + это сложение, но оно РАЗНОЕ, в зависимости от слагаемых. А иногда даже НЕ ОПРЕДЕЛЁННОЕ (если компилятор смог распарсить, что сложение не определено(как выше), он откажется собирать. Но можно скрыть эту ошибку(кастом в ptrdiff_t например), тогда всё соберётся(но получится HEX)).

Причём я настаиваю на том, что это синтаксическая ошибка, а вовсе не какая-то другая. Конструкция указатель+указатель не имеет смысла синтаксически.

А вот семантически, сложение указателей имеет смысл: значение указателя — натуральное число(за двумя исключениями: 1. есть NULL, 2. множество ограничено каким-то большим натуральным числом). Складывать натуральные числа можно(с учётом ограничений конечно).

Тогда foo(1,2,3) - контекст foo( ), 8+1,2,3+9 - контекст 8+ +9. Запятые трансформируются в разные AST?

в C/C++ запятые трансформируются в несколько деревьев. В стандарте это называется «точки следования». У тебя тут три дерева, и в данном случае порядок их вычисления не определён(в данном контексте у запятой необычный смысл. Обычно 1,2,3 синтаксически одно AST, в котором вычисляется 1, потом 2, а потом 3. Причём результат это 3). У трёх деревьев три результата.

emulek
()
Ответ на: комментарий от anonymous
f(x, y, z);
x, y, z;

В первом случае запятая парсится в рамках нетерминала argument_list, а во втором в рамках нетерминала expression. Здесь нет зависимости от контекста: парсер знает, в какой нетерминал он свёрнёт последовательность.

что за бред ты пишешь? Разве ты не видишь, что запятые имеют совершенно разный смысл? Какой «нетерминал» выбирать решает либастрал что-ли?

emulek
()
Ответ на: комментарий от anonymous

У тебя в дкн ошибка.

ты даже чужую шутку скопипастить не смог...

emulek
()
Ответ на: комментарий от no-such-file

Но парсится-то она по-разному. Так и в вашем примере можно сказать, что всё выражение парсится в рамках нетерминала translation_unit, т.е. вся единица трансляции - нетерминал.

Еще раз. Ты говоришь, что запятая имеет разный СМЫСЛ. Но. Смысл высказывания на языке не является предметом формальной грамматики. Формальная грамматика только отвечает на вопрос, является ли входная последовательность допустимой для данного языка (что с практической точки зрения эквивалентно возможности построить AST).

При построении парсера для ЯП нас интересует конкретный класс формальной грамматики: какой именно автомат сможет распознать данную грамматику. В Си пример с a * b однозначно распознать КС-автоматом нельзя. А пример с x, y, z - можно.

Тебе понятно, в чем разница между примерами? Почему пример с x, y, z можно распознать КС-автоматом тебе ясно, или нужны пояснения?

anonymous
()
Ответ на: комментарий от anonymous

«стул умножить на стул»

не так. «ты лужа пёрнул запах цветы не»

emulek
()
Ответ на: комментарий от emulek

Разве ты не видишь, что запятые имеют совершенно разный смысл?

Смысл высказывания не является предметом изучения теории формальных грамматик.

Какой «нетерминал» выбирать решает либастрал что-ли?

Как правило, решает LR-автомат на основе спецификации грамматики. В общем случае, любой КС-автомат.

anonymous
()
Ответ на: комментарий от emulek

не имеет смысла синтаксически

У тебя каша в голове. Выражение твое просто не имеет смысла, т.е. оно семантически некорректно. Твоя ошибка - это ошибка типов, а не синтаксическая ошибка. Она распознается тайпчекером. А типы - это и есть контексты. Тайпчекер распознает ошибку на основе синтаксиса. Т.е. то что происходит - это синтаксический анализ. А грамматика - это сама возможность распознать.

anonymous
()
Ответ на: комментарий от emulek

значение указателя — натуральное число(за двумя исключениями: 1. есть NULL, 2. множество ограничено каким-то большим натуральным числом). Складывать натуральные числа можно(с учётом ограничений конечно).

Раз пошла такая пьянка, то значение указателя можно представить как элемент множества вычетов натуральных чисел и нуля по модулю 2^N, где N - разрядность указателя. Складывать их можно без всяких ограничений.

в C/C++ запятые трансформируются в несколько деревьев

Спасибо КЭП.

В стандарте это называется «точки следования».

Ну а если это КС грамматика, то зачем специально определять в стандарте какие-то костыли? Там все само должно быть очевидно.

Т.е. + это сложение, но оно РАЗНОЕ, в зависимости от слагаемых

Важно то, что + это всегда выражение, а не что-то другое.

no-such-file ★★★★★
()
Ответ на: комментарий от anonymous

Контекстозависимость была бы, если бы твоя операция умножения умела работать с разными контекстами, т.е. операция зависела от контекста применения

оно так и есть. Только не «операция умножения», а «то, во что преобразуется звёздочка». Дело в том, что в C/C++ синтаксически звёздочка ≠ бинарное умножение.

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

у меня здесь сложение, и синтаксически binary+ тут(в данном контексте) не имеет смысла.

emulek
()
Ответ на: комментарий от anonymous

У тебя каша в голове.

Ему уже сто раз об этом сказано. Это же бывший dr batty, тяжелый случай.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.