Как построить код для такого выражения?
От: frogkiller Россия  
Дата: 27.07.07 11:49
Оценка:
Попалась мне книжка Э.Дейкстры аж 1976 года.
И там встретилась такая идея — рассматривать следующую запись для оператора присваивания:

<оператор присваивания> ::= <переменная> := <выражение> | <переменная>, <оператор присваивания>, <выражение>


Цель такого действия — естественная запись одновременного присваивания:
x1, x2 := E2, E1  =>  x1 := E1

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

А ещё я попытался построить автомат, который бы распознавал такие конструкции, но что-то никак не получается. Получается, что для него необходим в общем случае неограниченный объём памяти, т.е. реализуемая им грамматика не относится ни к LL(k), ни к LR(k), при том, что она линейная. Так?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Курица — это инструмент, с помощью которого одно яйцо производит другие.
Re: Как построить код для такого выражения?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 27.07.07 11:55
Оценка:
Здравствуйте, frogkiller, Вы писали:

F>Попалась мне книжка Э.Дейкстры аж 1976 года.

F>И там встретилась такая идея — рассматривать следующую запись для оператора присваивания:
F>

F><оператор присваивания> ::= <переменная> := <выражение> | <переменная>, <оператор присваивания>, <выражение>


F>Цель такого действия — естественная запись одновременного присваивания:

F>
F>x1, x2 := E2, E1  =>  x1 := E1
F>

F>Применяется ли где-нибудь такое? Так, чтобы в правой части были копии полученных выражений, а не ссылки.

F>А ещё я попытался построить автомат, который бы распознавал такие конструкции, но что-то никак не получается. :( Получается, что для него необходим в общем случае неограниченный объём памяти, т.е. реализуемая им грамматика не относится ни к LL(k), ни к LR(k), при том, что она линейная. Так?


Ну параллельное присваивание по типу

var1, var2 = exp1, exp2 (в результате одновременно var1<-exp1 и var2<-exp2)
есть много где (например, в Питоне). Но там не грамматическая проверка соответствия (или при компиляции, или runtime, но что-то над грамматикой проверяет соответствие количества аргументов слева и справа)

А у Дейкстры получается какой-то странный вариант — справа выражения в обратном порядке, что ли?
The God is real, unless declared integer.
Re[2]: Как построить код для такого выражения?
От: frogkiller Россия  
Дата: 27.07.07 12:27
Оценка:
Здравствуйте, netch80, Вы писали:

N>Ну параллельное присваивание по типу


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

N>var1, var2 = exp1, exp2 (в результате одновременно var1<-exp1 и var2<-exp2)

N>есть много где (например, в Питоне). Но там не грамматическая проверка соответствия (или при компиляции, или runtime, но что-то над грамматикой проверяет соответствие количества аргументов слева и справа)

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

N>А у Дейкстры получается какой-то странный вариант — справа выражения в обратном порядке, что ли?


Ну, это я немного развил его мысль . Сам Дейкстра описал этот вариант и указал, что получаемая семантика оператора отличается от общепринятой (как ты написал про Питон), и видимо поэтому не стал углубляться в дальнейший анализ. Фишка в том, что результатом самого внутреннего присваивания является не число, а следующий оператор присваивания (при этом само действие получается как побочный эффект что ли).
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Курица — это инструмент, с помощью которого одно яйцо производит другие.
Re: Как построить код для такого выражения?
От: SergH Россия  
Дата: 27.07.07 21:26
Оценка:
Здравствуйте, frogkiller, Вы писали:

F>Применяется ли где-нибудь такое? Так, чтобы в правой части были копии полученных выражений, а не ссылки.


Вот такое:

var1, var2 = exp1, exp2 (в результате одновременно var1<-exp1 и var2<-exp2)

Во всю применяется во всяких *HDL (Hardware Definition Language, языки описания аппаратуры). Там, конечно, всё не совсем так, как обычно. Справа и слева в таком присваивании находятся имена контактов, присваивание — соединение (не динамическое, ессно, на основе такого описания генерится схема без движущихся деталей ) Но компилятор это парсит и обрабатывает...

VHDL, AHDL, Verilog (с последним не сталкивался, но там такое должно быть обязательно )
Делай что должно, и будь что будет
Re: Как построить код для такого выражения?
От: Maxim S. Shatskih Россия  
Дата: 28.07.07 00:26
Оценка: +1
F>А ещё я попытался построить автомат, который бы распознавал такие конструкции, но что-то никак не получается. Получается, что для него необходим в общем случае неограниченный объём памяти, т.е. реализуемая им грамматика не относится ни к LL(k), ни к LR(k), при том, что она линейная. Так?

Если на уровне грамматики проверять равенство количества левых и правых сущностей — то она не то что не LL(1) будет, а вообще не контекстно-свободная.
Занимайтесь LoveCraftом, а не WarCraftом!
Re[2]: Как построить код для такого выражения?
От: frogkiller Россия  
Дата: 28.07.07 06:27
Оценка: 1 (1)
Здравствуйте, Maxim S. Shatskih, Вы писали:

F>>А ещё я попытался построить автомат, который бы распознавал такие конструкции, но что-то никак не получается. Получается, что для него необходим в общем случае неограниченный объём памяти, т.е. реализуемая им грамматика не относится ни к LL(k), ни к LR(k), при том, что она линейная. Так?


MSS>Если на уровне грамматики проверять равенство количества левых и правых сущностей — то она не то что не LL(1) будет, а вообще не контекстно-свободная.


Контекстно-зависимая — это вроде так:

aIb => axb


А здесь, насколько я понимаю, проще:

I => aIb
I => x


Т.е. грамматика всё-таки контекстно-свободная. Но вот привести её к правостороннему или левостороннему виду нельзя.

Я тут подумал, для простого распознавания по видимому достаточно автомата с неограниченым стеком (или регистром-счётчиком). Соответственно, для генерации последовательного кода (для классической стековой машины) этого должно быть тоже достаточно. Но при этом присваивание будет совсем не одновременным.
А вот для честного одновременного действия, при котором swap будет реализован одним оператором, по-видимому, потребуется второй стек.
Курица — это инструмент, с помощью которого одно яйцо производит другие.
Re: Как построить код для такого выражения?
От: Centaur Россия  
Дата: 30.07.07 06:50
Оценка:
Здравствуйте, frogkiller, Вы писали:

F>Попалась мне книжка Э.Дейкстры аж 1976 года.

F>И там встретилась такая идея — рассматривать следующую запись для оператора присваивания:
F>

F><оператор присваивания> ::= <переменная> := <выражение> | <переменная>, <оператор присваивания>, <выражение>


Данная грамматика неправильно отражает семантику конструкции. Попробуем, например, разобрать выражение "a, b = c, d":

<оператор_присваивания>
  <переменная>a</переменная>
  <оператор_присваивания>
    <переменная>b</переменная>
    <выражение>c</выражение>
  </оператор_присваивания>
  <выражение>d</выражение>
</оператор_присваивания>


Спрашивается, какой смысл имеет <оператор присваивания> (b = c) внутри, если на самом деле хочется эквивалентность (a = b; c = d)?

Грамматика должна быть примерно такой:
<оператор присваивания> ::= <список переменных> := <список выражений>
<список переменных> ::= <переменная> ( <запятая> <переменная> )*
<список выражений> ::= <выражение> ( <запятая> <выражение> )*

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

external function gmdate() returns (integer, integer, integer);
external function intToString(integer) returns string;

const genitiveMonthName: map[int => string] = (
  1 => "января", 2 => "февраля", 3 => "марта",
  4 => "апреля", 5 => "мая", 6 => "июня",
  7 => "июля", 8 => "августа", 9 =>"сентября",
  10 => "октября", 11 => "ноября", 12 => "декабря");

function dateAsString() returns string =
let
  (y, m, d) = gmdate()
in
  intToString(d) || " " ||
  genitiveMonthName[m] || " " ||
  intToString(y) || " года"
end;

В данном случае я бы рекомендовал требовать заключать списки для множественного присваивания в скобки, поскольку конструкция "let a = b, c = d in X end" так же вероятна, как и "let a, c = b, d in X end", и нужно мочь правильно разбирать, где чему что присваивается. А требование писать "let (a, c) = (b, d)" интуитивно понятнее, чем требование писать "let (a = b), (c = d)".
Re: Как построить код для такого выражения?
От: Sm0ke Россия ksi
Дата: 31.07.07 07:41
Оценка:
Здравствуйте, frogkiller, Вы писали:

F>Попалась мне книжка Э.Дейкстры аж 1976 года.

F>И там встретилась такая идея — рассматривать следующую запись для оператора присваивания:
F>

F><оператор присваивания> ::= <переменная> := <выражение> | <переменная>, <оператор присваивания>, <выражение>


F>Цель такого действия — естественная запись одновременного присваивания:

F>
F>x1, x2 := E2, E1  =>  x1 := E1
F>

F>Применяется ли где-нибудь такое? Так, чтобы в правой части были копии полученных выражений, а не ссылки.

F>А ещё я попытался построить автомат, который бы распознавал такие конструкции, но что-то никак не получается. Получается, что для него необходим в общем случае неограниченный объём памяти, т.е. реализуемая им грамматика не относится ни к LL(k), ни к LR(k), при том, что она линейная. Так?


Если бы шаблонные токены?...
<присваивание>{N} ::= <перименная> (<запятая> <присваивание>{N+1} | ':=' <список выражений>{N})

<список выражений>{N} ::= <выражение> <запятая> <список выражений>{N-1}
<список выражений>{1} ::= <выражение>
Re[2]: Как построить код для такого выражения?
От: Sm0ke Россия ksi
Дата: 31.07.07 07:47
Оценка:
Здравствуйте, Sm0ke, Вы писали:

S>Если бы шаблонные токены?...

Забыл вход в цикл =)
<множественное присваивание> ::= <присваивание>{1}
S><присваивание>{N} ::= <перименная> (<запятая> <присваивание>{N+1} | ':=' <список выражений>{N})

S><список выражений>{N} ::= <выражение> <запятая> <список выражений>{N-1}
S><список выражений>{1} ::= <выражение>
S>


Шаблоны рулят!
Re[2]: Как построить код для такого выражения?
От: frogkiller Россия  
Дата: 31.07.07 14:42
Оценка:
Здравствуйте, Centaur, Вы писали:

C>Данная грамматика неправильно отражает семантику конструкции. Попробуем, например, разобрать выражение "a, b = c, d":


C>[...]


C>Спрашивается, какой смысл имеет <оператор присваивания> (b = c) внутри, если на самом деле хочется эквивалентность (a = b; c = d)?


Ты, наверное, имел ввиду (a = c; b = d)? И кто сказал, что хочется именно этого? Одинаковый порядок слева и справа — лишь традиция, и в принципе ничто не мешает нам её изменить, если это позволит упростить реализацию. Тот же форт с польской нотацией вполне себе используется.
Курица — это инструмент, с помощью которого одно яйцо производит другие.
Re[3]: Как построить код для такого выражения?
От: Sm0ke Россия ksi
Дата: 31.07.07 15:31
Оценка:
Здравствуйте, frogkiller, Вы писали:

F>Здравствуйте, Centaur, Вы писали:


C>>Данная грамматика неправильно отражает семантику конструкции. Попробуем, например, разобрать выражение "a, b = c, d":


C>>[...]


C>>Спрашивается, какой смысл имеет <оператор присваивания> (b = c) внутри, если на самом деле хочется эквивалентность (a = b; c = d)?


F>Ты, наверное, имел ввиду (a = c; b = d)? И кто сказал, что хочется именно этого? Одинаковый порядок слева и справа — лишь традиция, и в принципе ничто не мешает нам её изменить, если это позволит упростить реализацию. Тот же форт с польской нотацией вполне себе используется.


В перле кажется можно так:
($a, $b, $c)= reverse (3, 2, 1);
Re: Как построить код для такого выражения?
От: Кодт Россия  
Дата: 02.08.07 13:34
Оценка: 1 (1)
Здравствуйте, frogkiller, Вы писали:

F>Применяется ли где-нибудь такое? Так, чтобы в правой части были копии полученных выражений, а не ссылки.


Да сколько угодно.
# python

# кортежу переменных можно присвоить кортеж значений
x,y,z = 1,2,3 # x=1, y=2, z=3

# переменной можно присвоить кортеж
xyz = 1,2,3 # x=(1, 2, 3)

# кортежу переменных можно присвоить значение-кортеж
x,y,z = xyz # x=1, y=2, z=3

# трюки
x,y = xyz # ошибка арности
x,y,z,t = xyz # опять ошибка арности
x,y,x = xyz # x=3, y=2 - присваивание идёт слева направо, запоминается последнее :)

Это вовсю используется в функциональном программировании, где кортеж является основным алгебраическим типом.

Да, кстати, и на С++ можно
#include <boost/tuple.hpp>
using namespace boost;
.....
int x, y, z;
tie(x, y, _, z) = make_tuple(1,2,3,4); // кажется, так


F>А ещё я попытался построить автомат, который бы распознавал такие конструкции, но что-то никак не получается. Получается, что для него необходим в общем случае неограниченный объём памяти, т.е. реализуемая им грамматика не относится ни к LL(k), ни к LR(k), при том, что она линейная. Так?


А зачем взваливать на парсер проверку семантики? Пусть это делает следующая ступень транслятора.
Слева и справа должны быть однотипные выражения. В данном случае информация о типе — это, как минимум, арность кортежа.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[2]: Как построить код для такого выражения?
От: frogkiller Россия  
Дата: 02.08.07 14:34
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, frogkiller, Вы писали:


F>>Применяется ли где-нибудь такое? Так, чтобы в правой части были копии полученных выражений, а не ссылки.

К>Да сколько угодно.
[...]
К>Это вовсю используется в функциональном программировании, где кортеж является основным алгебраическим типом.

Кстати, здесь несколько другая семантика, первый-с-первым. И именно поэтому требуется такой специфический тип данных как кортеж. В моём случае несколько иначе, и векторные переменные вводить необязательно.

К>Да, кстати, и на С++ можно

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

F>>А ещё я попытался построить автомат, который бы распознавал такие конструкции, но что-то никак не получается. Получается, что для него необходим в общем случае неограниченный объём памяти, т.е. реализуемая им грамматика не относится ни к LL(k), ни к LR(k), при том, что она линейная. Так?

К>А зачем взваливать на парсер проверку семантики? Пусть это делает следующая ступень транслятора.
К>Слева и справа должны быть однотипные выражения. В данном случае информация о типе — это, как минимум, арность кортежа.

Имхо, соответствие количества элементов слева и справа — всё-таки синтаксис. Семантика (информация о типе или арность кортежа) появляется только с введением этого типа, чего я, собственно, и хочу избежать.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Курица — это инструмент, с помощью которого одно яйцо производит другие.
Re[3]: Как построить код для такого выражения?
От: Кодт Россия  
Дата: 02.08.07 15:01
Оценка:
Здравствуйте, frogkiller, Вы писали:

F>Кстати, здесь несколько другая семантика, первый-с-первым. И именно поэтому требуется такой специфический тип данных как кортеж. В моём случае несколько иначе, и векторные переменные вводить необязательно.


Ну можно, конечно, сделать так
<Assign> ::= <Var> <Operator> <Expr>
<Operator> ::=  ':=' | ',' <Assign> ','

Но вообще, это отдаёт маразмом. Есть общепринятая и легко читаемая нотация. Зачем на ровном месте делать форт?
z, y, x := x0, y0, z0


F>>>А ещё я попытался построить автомат, который бы распознавал такие конструкции, но что-то никак не получается. Получается, что для него необходим в общем случае неограниченный объём памяти, т.е. реализуемая им грамматика не относится ни к LL(k), ни к LR(k), при том, что она линейная. Так?

К>>А зачем взваливать на парсер проверку семантики? Пусть это делает следующая ступень транслятора.
К>>Слева и справа должны быть однотипные выражения. В данном случае информация о типе — это, как минимум, арность кортежа.

F>Имхо, соответствие количества элементов слева и справа — всё-таки синтаксис. Семантика (информация о типе или арность кортежа) появляется только с введением этого типа, чего я, собственно, и хочу избежать.


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

Никто же не заставляет реально работать с алгебраическими типами — пусть они незримо присутствуют и развёртываются ещё на стадии трансляции.
То есть, парсер строит дерево
       ':='
    ___/ \___
 ','         ','
 / \         / \
x   ','     t   ','
    / \         / \
   y   z       u   v

и тут же (ну или когда нужно) транслятор проверяет арности слева-справа и превращает в (x=t),(y=u),(z=v) либо (x=v),(y=u),(z=t) — как тебе больше нравится.
Опять же, только блок семантики может определить — являются ли выражения слева настоящими lvalue (или, в более простом случае — объявлены ли эти переменные или ещё нет, можно ли им сделать первичное/повторное присваивание, нет ли повторений переменной в этом выражении — и т.д. и т.п.)
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[4]: Как построить код для такого выражения?
От: frogkiller Россия  
Дата: 02.08.07 15:42
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Ну можно, конечно, сделать так

К>
К><Assign> ::= <Var> <Operator> <Expr>
К><Operator> ::=  ':=' | ',' <Assign> ','
К>

К>Но вообще, это отдаёт маразмом. Есть общепринятая и легко читаемая нотация. Зачем на ровном месте делать форт?
К>
К>z, y, x := x0, y0, z0
К>


Э... вообще-то вроде именно это я и написал в самом первом посте. Вопрос был в том, как (и какой) автомат разберёт такую грамматику с проверкой соответствия количества элементов слева и справа.
По поводу общепринятой нотации, да. Но тут как раз дело привычки — так что аргумент несколько из другой области. Форт всё же кое-где используется.

F>>Имхо, соответствие количества элементов слева и справа — всё-таки синтаксис. Семантика (информация о типе или арность кортежа) появляется только с введением этого типа, чего я, собственно, и хочу избежать.

К>А интересно, проверять арность вызова функции — ты тоже собираешься в парсер запихивать?
К>Если твой парсер знает об арностях каждого символа, это уже контекстно-зависимая грамматика.

Не. Вот это как-раз семантика. Или контекстно-зависимая грамматика, как ты отметил, с ней всё сложно, и оно, наверное, не оправдано. А тут контекстно-свободная грамматика, более того, линейная. Почему-бы не вынести часть функциональности следующих слоёв сюда, где, на мой взгляд ей и место?

К>Никто же не заставляет реально работать с алгебраическими типами — пусть они незримо присутствуют и развёртываются ещё на стадии трансляции.

К>То есть, парсер строит дерево
К>
К>       ':='
К>    ___/ \___
К> ','         ','
К> / \         / \
К>x   ','     t   ','
К>    / \         / \
К>   y   z       u   v
К>

К>и тут же (ну или когда нужно) транслятор проверяет арности слева-справа и превращает в (x=t),(y=u),(z=v) либо (x=v),(y=u),(z=t) — как тебе больше нравится.

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

К>Опять же, только блок семантики может определить — являются ли выражения слева настоящими lvalue (или, в более простом случае — объявлены ли эти переменные или ещё нет, можно ли им сделать первичное/повторное присваивание, нет ли повторений переменной в этом выражении — и т.д. и т.п.)


Это да, и как раз задача для блока семантики.



Сейчас добуду Ахо,Сети,Ульмана и буду перечитывать вторую главу.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Курица — это инструмент, с помощью которого одно яйцо производит другие.
Re[3]: Как построить код для такого выражения?
От: Кодт Россия  
Дата: 02.08.07 15:51
Оценка: 2 (1)
Здравствуйте, frogkiller, Вы писали:

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


Сейчас думал над тем, как похожее сделать на С++.

Беда в том, что запятая слева от := правоассоциативна, а справа — левоассоциативна. При этом они имеют одинаковый приоритет.
В С++ нет такой пары операторов, так что даже всякими фокусами с перегрузкой такого не достичь, оставаясь в пределах парсера.

Ну а так — пожалуйста. Выражение должно выглядеть примерно так:
int main()
{
    int x, y, z;
    x <<= y <<= z <<=assign>> 3 >> 2 >> 1;
    // скобки расставятся так:
    x <<= (y <<= (z <<= (((assign >> 3) >> 2) >> 1)));
//        \      \      \\\___________/     /     ///
//         \      \      \\________________/     ///
//          \      \      \_____________________///
//           \      \___________________________//
//            \_________________________________/
}

Надо построить expression template, которое
— из assign>>3>>2>>1 сделает cons-список [3,2,1] (добавляя элементы в хвост)
— из этого списка по <<= будет выдёргивать головной элемент и присваивать тому, что справа

Если арность переменных меньше, чем арность значений, то компилятор это не распознает. Чтобы распознал, нужен ещё один маркер.
set<<= x <<= y <<= z <<=equal_to>> 3 >> 2 >> 1;

так, что <<=(Set,T) определён только над сбалансированным выражением присваивания T.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[5]: Как построить код для такого выражения?
От: Кодт Россия  
Дата: 02.08.07 16:52
Оценка: 14 (2)
Здравствуйте, frogkiller, Вы писали:

F>Э... вообще-то вроде именно это я и написал в самом первом посте. Вопрос был в том, как (и какой) автомат разберёт такую грамматику с проверкой соответствия количества элементов слева и справа.


Стековый разберёт.
Правила у него вот такие
                  '{' | Var(x)  --> '{' Var(x)            -- { x
               Var(x) | ','     --> Var(x) ','            -- x ,
           Var(y) ',' | Var(x)  --> Var(y) ',' Var(x)     -- y , x
               Var(x) | ':='    --> Var(x) ':='           -- x :=
          Var(x) ':=' | Expr(e) --> '<:=>'                -- x := e       -- выполняем присваивание, сворачиваем
    Var(x) ',' '<:=>' | ','     --> Var(x) ',' '<:=>' ',' -- x , <:=> ,
Var(x) ',' '<:=>' ',' | Expr(e) --> '<:=>'                -- x , <:=> , e -- выполняем присваивание, сворачиваем
           '{' '<:=>' | ';'     --> '{'                   -- { <:=> ;     -- стейтмент завершён, выбрасываем
           '{' '<:=>' | '}'     --> '{}'                  -- { <:=> }     -- стейтмент завершён, блок завершён
                  '{' | '}'     --> '{}'                  -- { }          -- блок завершён

Здесь я для наглядности не стал превращать последовательности терминальных символов в нетерминальные.
Но можно это и сделать.
                Block | Var(x)  --> Block Var(x)          -- { x
               Var(x) | ','     --> VarC(x)               -- x,
              VarC(y) | Var(x)  --> VarC(y) Var(x)        -- y, x
               Var(x) | ':='    --> VarA(x)               -- x:=
              VarA(x) | Expr(e) --> AE                    -- x:=e      --> <:=>
           VarC(x) AE | ','     --> VarA(x)               -- x, <:=> , --> x:=
             Block AE | ';'     --> Block                 -- { <:=> ;  --> {
             Block AE | '}'     --> Body                  -- { <:=> }  --> {}
                Block | '}'     --> Body                  -- {}


В классификации — LL(k), LR(k) — я не шибко силён, нужно Ухо перечитывать.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[3]: Как построить код для такого выражения?
От: . Великобритания  
Дата: 02.08.07 21:02
Оценка:
frogkiller wrote:

> Имхо, соответствие количества элементов слева и справа — всё-таки

> синтаксис. Семантика (информация о типе или арность кортежа) появляется
> только с введением этого типа, чего я, собственно, и хочу избежать.
А собственно зачем? Чисто академический интерес? А если всё-таки есть какая-то практическая ценность, то чем вариант
x=1;y=2;z=3;

не устраивает?
ценность кортежей не в присваивании пачек переменных друг другу, а в штуках подобных:
(x,y,_,z) = func(5);

что таким синтаксисом в принципе не покрывается.
Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[4]: Как построить код для такого выражения?
От: frogkiller Россия  
Дата: 03.08.07 08:28
Оценка:
Здравствуйте, ., Вы писали:

>> Имхо, соответствие количества элементов слева и справа — всё-таки

>> синтаксис. Семантика (информация о типе или арность кортежа) появляется
>> только с введением этого типа, чего я, собственно, и хочу избежать.
.>А собственно зачем? Чисто академический интерес? А если всё-таки есть какая-то практическая ценность, то чем вариант
.>
x=1;y=2;z=3;

.>не устраивает?

Интерес скорее академический. Просто подумал, 30 лет назад придумали такую штуку, на мой взгляд довольно интересную, но использовать не стали. Значит, это чем-то обусловлено, но только ли традицией записи?
Как раз где-то в то время Дейкстра хотел описать свой язык и компилятор к нему, но, по-видимому, был сильно занят чем-то другим. А так, глядишь, и такую семантику присваивания считали бы вполне нормальной.

.>ценность кортежей не в присваивании пачек переменных друг другу, а в штуках подобных:

.>
(x,y,_,z) = func(5);

.>что таким синтаксисом в принципе не покрывается.

Разумеется, но кортежи — это всё-таки отдельная песня, и их введение в язык существенно усложняет его реализацию.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Курица — это инструмент, с помощью которого одно яйцо производит другие.
Re[5]: Как построить код для такого выражения?
От: Кодт Россия  
Дата: 03.08.07 10:27
Оценка:
Здравствуйте, frogkiller, Вы писали:

F>Разумеется, но кортежи — это всё-таки отдельная песня, и их введение в язык существенно усложняет его реализацию.


Это почему?
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.