Здравствуйте, VladD2, Вы писали:
VD>Но пучилось немного больше папчуров чем надо. Ведь если у нас есть терминальный капчур, то какой смысл внутри него еще какие-то капчуры держать? Они ему совершенно не нужны. Я когда генерацию кода присвоения переменных делал был вынужден из-за этого специальный параметр заводить чтобы обойти это безобразие. Так же он ломает и оптимизацию.
да мой косяк
здесь
else if(id.ToString() != string.Empty)
Rule.CaptureNamedTerminalSymbol(id.ToString(), rule);
добавлю проверки: не внутри капчура или предиката
для именованных исправлю
VD>Если сможешь, выброси добавление терминальных капчуров если это происходит в подветке где уже есть терминальный капчур.
я это
учитывал:
private CanBeSplited(rule : Rule) : bool
{
| Chars => true
| CaptureNamedTerminalSymbol
| Capture
| Call => false
т.е. внутри капчура и вызова, неименованные термы не ищутся.
P>>я планировал ввести параметры макроса, в которых описывать какие терминальные символы нужны, а какие нет.
VD>Вот это как-то очень сложно. Нужны только те терминалы, что передаются в параметры методов обработчиков. Никаких дополнительных описаний не нужно.
я это и имею в виду.
вопрос в том, в каком виде макросу дать понять какие термы нужны, с точки зрения использования макроса
например, как обозначить что
//в обрабочике
private mulOrDiv(se : VToken[int], lst : List[NToken * NToken * VToken[int]]) : int
//на саммом деле нужно
private mulOrDiv(se : VToken[int], lst : List[NToken * VToken[int]]) : int
//где первый элемент кортежа в списке это Term[unnamed_terminal_rule_xxx]('/' / '*')
Здравствуйте, para, Вы писали:
P>вопрос в том, в каком виде макросу дать понять какие термы нужны, с точки зрения использования макроса
P>например, как обозначить что
P>P> //в обрабочике
P> private mulOrDiv(se : VToken[int], lst : List[NToken * NToken * VToken[int]]) : int
P> //на саммом деле нужно
P> private mulOrDiv(se : VToken[int], lst : List[NToken * VToken[int]]) : int
P> //где первый элемент кортежа в списке это Term[unnamed_terminal_rule_xxx]('/' / '*')
P>
Нужно сформировать описание сигнатуры и сравнить ее с сигнатурой метода-обработчика. Если они не совпадают нужно выдать сообщение об ошибке в котором сказать: "
Неверная сигнатура метода-обработчика 'mulOrDiv'. Требуется сигнатура mulOrDiv(secondExpr : VToken[int], loop : List[NToken /* '+' / '_' */ * VToken[int] /* secondExpr */]) : int". При этом в сообщении должен быть задан локешон этого скамого метода обработчика.
Тогда программист использующих макрос сможет понять в чем он был не прав и исправить ошибку. За одно он сможет использовать текст из сообщения об ошибки для формирования каркаса метода-обработчика (методом копи-пэст).
Если программист хочет игнорировать какие-то правила в конкретном обработчике, то можно попробовать ввести дополнительную аннотацию. Скажем не нужные правила он может перечислять в мета-атрибуте, или просто давать им вместо имени "_" (что делается и сейчас). Проблема только в том, что при этом придется описывать тип параметра, так как боюсь что Немерле не позволит опускать его у параметров. В прочем, можно подкрутить компилятор так чтобы он позволял это делать, а проверял наличие типов у методов на более поздних стадиях.