Здравствуйте, hi_octane, Вы писали:
Tom>>Причём тут вообще IQ, я даже при очень большом желании использовать немерл не смогу пробить стену мэнеджмента который справедливо боится что поддержка сего проекта закончится сразу после того как кто то не ухватится за новую супер пупер идею, как это было с R#
_>Если вы общаетесь с МС как все, через connect, и прямой линии к Хельсбергу и Co у вас нету — то поддержка которую оказывает МС де факто _хуже_ чем поддержка которую можно получить на форуме Nemerle. Кроме того у вас есть возможность и смотреть в сорцы компилятора, и в крайнем случае даже поправить самим. Код компилятора на самом деле вполне обозримого размера, именно из-за того что написан на себе-же и при сборке сам себя тестирует.
Когда берётся стороннее решение, то оно берётся не столько из-за того, что оно уже написано. Сколько из-за того, что издержки на поддержку этого решения нулевые. Неважно, опен-сорс или нет.
Здравствуйте, adontz, Вы писали:
A>Пусть будет два рабочих дня и ещё умножим на ва, как поступают менеджеры со сроками программистов. Итого 11го числа баги будут исправлены. Ну-ну.
Синтаксические ошибки обычно достаточно быстро исправляются. Единственный затык который возможен это проблемы с генератором парсеров, например он что-то не умеет и тогда приходится приделывать костыли.
Здравствуйте, VladD2, Вы писали:
H>>У нас нет понятия токен. Это безлексерный парсер. VD>И все же && отличить от & можно, а в случае шарпа — нужно.
А это сложно сделать, если нет лексера? За счет приоритетов как-то решается?
++v парсится как инкремент а не два плюса из за того что у ++ приоритет при парсинге выше?
Здравствуйте, Silver_s, Вы писали:
S_> А это сложно сделать, если нет лексера? За счет приоритетов как-то решается? S_> ++v парсится как инкремент а не два плюса из за того что у ++ приоритет при парсинге выше?
Это решается через синтаксические предикаты.
Те + нужно парсить не так
"+"
а вот так
"+" !"+"
!правило
Проверяет матчится ли правило и если матчится то происходит откат.
При этом в любом случае текст скушан не будет.
Тк можно использовать любое правило то это фактически способ заглянуть вперед на произвольное колличество символов.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, Silver_s, Вы писали:
H>>>У нас нет понятия токен. Это безлексерный парсер. VD>>И все же && отличить от & можно, а в случае шарпа — нужно.
S_> А это сложно сделать, если нет лексера?
Нет, не трудно.
S_>За счет приоритетов как-то решается?
В PEG работает правило — кто первый тот и папа. Так что если перед разбором оператора "&" попытаться разобрать "&&" и попытка окажется удачной, то попытки разобрать "&" даже не будет производиться.
Я не знаю в чем конкретная ошибка, но скорее всего дело в том, что "&" — это унарный префиксный оператора, а "&&" бинарный инфиксный. Они разбираются в отдельных контекстах, и так как в контексте префиксных операторов нет "&&", то последовательность && разбирается как & & expr (т.е. как последовательное применение оператора & к своему же результату). В принципе — это не проблема, так как на этапе семантического анализа такое применение будет отвергнуто.
Но конечно же можно потребовать, чтобы за оператором "&" не мог идти второй такой же. Сделать это не сложно. Для этого нужно задать негативный предикат. Выглядеть это будет примерно так:
"&" ! "&"
При этом, если парсер встретит последовательность "&&" в контексте разбора оператора "&", то он просто сфайлит и будет разобран другой путь, или выдано сообщение об ошибке.
S_> ++v парсится как инкремент а не два плюса из за того что у ++ приоритет при парсинге выше?
Здравствуйте, VladD2, Вы писали:
VD>В PEG работает правило — кто первый тот и папа. Так что если перед разбором оператора "&" попытаться разобрать "&&" и попытка окажется удачной, то попытки разобрать "&" даже не будет производиться.
А что мешает применить жадное правило (кто больше символов съел, тот и папа), или даже совместить и использовать приоритеты и жадные правила вместе по контексту?
У жадного разбора один недостаток — нужно попробовать ВСЕ варианты. Реальную проблему это приносит лишь при больших откатах.
Здравствуйте, Silver_s, Вы писали:
H>>>У нас нет понятия токен. Это безлексерный парсер. VD>>И все же && отличить от & можно, а в случае шарпа — нужно.
S_> А это сложно сделать, если нет лексера? За счет приоритетов как-то решается? S_> ++v парсится как инкремент а не два плюса из за того что у ++ приоритет при парсинге выше?
Поясню еще раз. Безлексерный парсер штука очень гибкая. Но эта же гибкость может приводить к казусам подобным обсуждаемому, так как операторы и ключевые словам по сути становятся контекстными. Это требует предпринимать дополнительные действия чтобы обеспечить их "глобальность".
Это правило говорит, что префиксными операторами могут быть перечисленные строки за которыми могут идти необязательные пробельные символы (которые описываются правилом s). Другими словами пробелов может и не идти.
А вот как выглядит правило описывающее выражение с префиксными операторами:
Не трудно понять, что по этому правил допустимой будет любая строка состоящая из символов "+-~!&*". Таким образом строка "&&" и даже строка "&&&" считаются допустимыми. Чтобы предотвратить это можно добавить предикат запрещающий разбор идущих подряд символов "&":
Здравствуйте, Алексей., Вы писали:
A>>Пусть будет два рабочих дня и ещё умножим на ва, как поступают менеджеры со сроками программистов. Итого 11го числа баги будут исправлены. Ну-ну.
А>Синтаксические ошибки обычно достаточно быстро исправляются. Единственный затык который возможен это проблемы с генератором парсеров, например он что-то не умеет и тогда приходится приделывать костыли.
С PEG-ом — это не тот случай. Предикаты позволяют разрулить любые проблемы.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, samius, Вы писали:
S>А что мешает применить жадное правило (кто больше символов съел, тот и папа), или даже совместить и использовать приоритеты и жадные правила вместе по контексту?
Все привила в PEG-е жадные. Они будут "есть" столько символов сколько смогут. А приоритетный выбор позволяет предпочесть одно из правил, если есть два правила которые способны разобрать строку.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
VD>>В нем вместо параметров left и left указаны плэйсходеры — "_". Так как плэйсхолдеры сопоставляются со всем чем угодно (даже с null), то мы получим требуемый результат. VD>>Кстати, Identifier — это не вариант, а простой класс. Так что "Identifier where(id="==")" — это поттерн-матчинг по объекту.
_FR>Ага, и поэтому Id с большой буквы?
Да, так как это свойство.
_FR>Имхо, в этом плохого ничего нет, наоборот понятно, что проверяется свойство Id.
Плохо в этом — многословность. При некоторых объемах образцы становятся нечитабельными. Краткость очень важна для образцов.
_FR>То, что Identifier с большой буквы тоже говорит о том, что это имя типа.
Да. В принципе класс конечно же можно назвать с маленькой буквы, но при этом будут проблемы в паттерн-матчинге. Они тоже могут быть обойдены за счет задания квалифицированного имени, но все же.
_FR>В строке _FR>
_FR>в ПаскальКейсе только "Identifier" и "Id" — о каких параметрах речь? Непосредственно к вариантам класс "Identifier" отношения не имеет.
Параметром, в данном случае является "op".
_FR>То есть сейячас речь о Record-ах?
Нет. [Record] — это просто макрос автоматически формирующий конструктор для всех полей. Собственно для вхождений вариантов он и используется.
_FR>Так там тоже поля получаются Почему нельзя сделать так же: пользователь указывает _FR>
_FR> [Record]
_FR> public class Identifier : Located
_FR> {
_FR> [Accessor] Id : string;
_FR> public override ToString() : string
_FR> {
_FR> id
_FR> }
_FR> }
_FR>
_FR>а параметр конструктора называется "id"? А свойство — Id.
Почему нельзя? Можно. Просто бессмысленно делать свойство для публичного поля. А делать его не публичным нельзя по той причине, что поля варианта входящие в конструктор должны быть публичными.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, samius, Вы писали:
S>>А что мешает применить жадное правило (кто больше символов съел, тот и папа), или даже совместить и использовать приоритеты и жадные правила вместе по контексту?
VD>Все привила в PEG-е жадные. Они будут "есть" столько символов сколько смогут. А приоритетный выбор позволяет предпочесть одно из правил, если есть два правила которые способны разобрать строку.
Я про то, что вместо приоритетов выбирать то правило из альтернативных, которое откусило больше от строки.
Здравствуйте, VladD2, Вы писали:
VD>Но конечно же можно потребовать, чтобы за оператором "&" не мог идти второй такой же. Сделать это не сложно. Для этого нужно задать негативный предикат. Выглядеть это будет примерно так: VD>
VD>"&" ! "&"
VD>
Так наверно лучше, в том числе учесть и &=
И наверно не только для C# . А вобще для всех операторов составленых из нескольких терминальных символов, лучше гибкость парсера в этом месте попридержать.
v1-+v2 Это в C# бинарный минус и унарный плюс, а это ошибка v1--v2
Можно конечно придумать грамматику в которой так и задумано — если нет слева операнда то распознается как декремент --v2,
если есть то распознается как v1 — (-v2). Но это была бы нехорошая грамматика, трудно читаемая. Что-то я не припомню чтобы такое было хоть в одном языке, такая контекстная зависимость (по крайней мере для операторов из нескольких терминальных символов).
Для языков где много таких составных операторов, может какие-то костыли приделать?
Чтобы указать все такие цепочки символов (операторы), и указать ограничение что они взаимно исключающие — если одна длинная цепочка подходит, значит нельзя считать как две коротких. А по ним уже автоматом нагенерировать правил с негативными предикатами.
Иначе, если захочется добавить новый оператор +- , прийдется его описать, потом еще "+" изменять.
Гибкость от этого сильно не пострадает, как от введения отдельной фазы лексического анализа.
Хотя может и руками не проблема вбить все предикаты с негативными частями.
Здравствуйте, Silver_s, Вы писали:
S_>И наверно не только для C# . А вобще для всех операторов составленых из нескольких терминальных символов, лучше гибкость парсера в этом месте попридержать. S_> v1-+v2 Это в C# бинарный минус и унарный плюс, а это ошибка v1--v2 S_>Можно конечно придумать грамматику в которой так и задумано — если нет слева операнда то распознается как декремент --v2, S_>если есть то распознается как v1 — (-v2). Но это была бы нехорошая грамматика, трудно читаемая. Что-то я не припомню чтобы
Особенно как читать
v1-----v2
Пятый левый минус бинарный потом два декремента. Или справа два минуса это декремент, слева бинарный, а между ними унарные. Черезмерно интеллектуальный гибкий парсер бы это разобрал, нашел правильный вариант, т.к. два декремента нельзя.
Но читатель бы не осилил такую запись. Так что такие ограничения в грамматике на предикатах с ! очень нужны для таких операторов
Здравствуйте, Silver_s, Вы писали:
VD>>Но конечно же можно потребовать, чтобы за оператором "&" не мог идти второй такой же. Сделать это не сложно. Для этого нужно задать негативный предикат. Выглядеть это будет примерно так: VD>>
VD>>"&" ! "&"
VD>>
S_> Так наверно лучше, в том числе учесть и &=
Зачем? На всякий пожарный? "=" и так отсутствует в списке.
S_> v1-+v2 Это в C# бинарный минус и унарный плюс, а это ошибка v1--v2
Ну, так и будет ошибка. "--" распознается как постфиксный оператор.
ЗЫ
Не надо искать глубокий философский смысл в баге.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали: S_>> Так наверно лучше, в том числе учесть и &= VD>Зачем? На всякий пожарный? "=" и так отсутствует в списке.
Оно из другого списка. Наверно, на всякий случай , для большей гарантии, что именно та ошибка отловится, и что лишнего не распарсит.
Как-то мне неочевидно в такой грамматике какая ошибка здесь будет:
4 &= v1
Это ошибка в любом случае. Но какая. Правый операнд у бинарного & неправильный, или левый операнд у &= неправильный
VD>Не надо искать глубокий философский смысл в баге.
Смысл бы только был в сообщениях компилятора об ошибках. И лучше не философский о высоком как сейчас в F#, а поконкретнее как в C#
S_>Как-то мне неочевидно в такой грамматике какая ошибка здесь будет: S_>4 &= v1 S_>Это ошибка в любом случае. Но какая. Правый операнд у бинарного & неправильный, или левый операнд у &= неправильный
Нет, я тут погрорячился. Тут неоднозначности быть не может.
Здравствуйте, Silver_s, Вы писали:
S_>Здравствуйте, VladD2, Вы писали: S_>>> Так наверно лучше, в том числе учесть и &= VD>>Зачем? На всякий пожарный? "=" и так отсутствует в списке. S_> Оно из другого списка. Наверно, на всякий случай , для большей гарантии, что именно та ошибка отловится, и что лишнего не распарсит.
Вот делать что-то на всякий случай, то есть бездумного, не стоит. Будет только хуже. Когда что-то делаешь нужно понимать зачем это делается и к чему это приведет. А то можно такого накосячить.
S_>Как-то мне неочевидно в такой грамматике какая ошибка здесь будет: S_>4 &= v1 S_>Это ошибка в любом случае. Но какая. Правый операнд у бинарного & неправильный, или левый операнд у &= неправильный
Тут как раз все очевидно. Постфиксного "&" нет.
VD>>Не надо искать глубокий философский смысл в баге. S_> Смысл бы только был в сообщениях компилятора об ошибках. И лучше не философский о высоком как сейчас в F#, а поконкретнее как в C#
Для создания парсера F# использует дремучее и кривое средство — клон yacc-а. Он основан на LALR-алгоритме, что сильно ухудшает диагностику ошибок.
В нашем парсере над диагностикой особо не работали, но по крайней мере он будет указывать место ошибки и писать что ожидалось в этом месте. Плюс есть возможность обеспечить более тонкую обработку (не усложняя при этом грамматику).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.