[Nitra] Первые впечатления и вопросы
От: Дьяченко Александр Россия  
Дата: 11.10.14 15:09
Оценка: 10 (2)

Предыстория

Был у меня персональный проект с разбором исходников на Модула-2 с использованием макроса peg-grammar, застрявший на этапе попытки сделать типизатор и в конце концов замороженный по причине нехватки времени.
Долго собирался попробовать переписать этот проект на Nitra, и вот наконец наконец собрался.

Установка

Скачал NemerleSetup-net-4.0-v1.2.391.0.msi и Nitra.Setup.msi (Nitra v0.1.1245.0 for .NET v4.0 installation package), поставил на VS2013 (Microsoft Visual Studio Professional 2013 Version 12.0.30723.00 Update 3).
Проблем при инсталляции никаких не было что уже хорошо, правда чтобы заработала подсветка пришлось перезагружаться (как я понял причина была в том что нужна была переменная окружения NitraPath, которую инсталятор хотя и создал, но была почему-то не видна до перезагрузки, может хватило бы и перелогиниться).

Первые шаги

Для начала попробовал создать грамматику для языка Модула-2, как результат за час я написал пол-страницы с 5 или 6 попытки .
В процессе VS2013 падала с концами 3 раза и еще несколько раз зависла.
Была предпринята попытка подцепиться отладчиком и попытаться найти причину.
В результате этой попытки было выяснено что похоже здесь виновата как интеграция с VS, так и компилятор Нитры.

Вопросы

Ну и наконец вопросы:
  1. [Nitra] Хотелось бы увидеть свежий Roadmap, нашел какой-то здесь, но он старый от мая 2013 (я уже спрашивал, но ответа не получил)
  2. [VS] Зачем обновлять кеш в UI потоке?
    Nitra / VisualStudioExtensions / Nitra.VisualStudio / Coloring / NitraClassifier.n:48
    parseAgent.ParseComplete +=
      fun(_, args)
      {
        def updateCache()
        {
          match (_classificationCache.Update(args.Result))
          {
            | Nothing => ()
            | All     => OnClassificationChanged(SnapshotSpan(args.Snapshot, 0, args.Snapshot.Length));
            | Ranges(rangesToUpdate) =>
              foreach(range in rangesToUpdate)
                OnClassificationChanged(SnapshotSpan(args.Snapshot, range.StartPos, range.Length));
          }
        }
        if (Thread.CurrentThread == NitraPackage.Instance.DataHostService.UIThread : object)
          updateCache();
        else
          _ = NitraPackage.Instance.DataHostService.BeginInvokeOnUIThread(Action(updateCache));
      };

    Вызывать OnClassificationChanged может и надо в UI потоке но обновлять кеш то зачем (смотри выделенное)?
  3. [VS] Почему в диалоге About версия 1.0?
    Nemerle   1.0
    Nemerle Visual Studio Integration
    Version 1.0
    
    Nitra Language Framework for Microsoft VisualStudio   1.0
    Nitra Language Framework helps developing domain specific languages (DSL)

  4. [Nitra] Сложилось впечатление что в парсере при восстановлении после ошибок есть ошибки
    Например вот такой код грамматики:
    syntax module Modula
    {
        syntax program_module = "MODULE" module_identifier [interrupt_protection] semicolon import_lists module_block module_identifier ".";
    }

    Порождает вот такое AST:
    syntax module Modula
    {
      syntax program_module = <# ambiguous RuleExpression, 64 options
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
        "MODULE" module_identifier ◄[►interrupt_protection ◄]► semicolon import_lists module_block module_identifier "."
      #>
      ;
    }

    А AST вот для такой грамматики:
    syntax module Modula
    {
        syn implementation_module =
          "IMPLEMENTATION", "MODULE", module_identifier,
          [interrupt_protection], semicolon,
            import_lists,
            module_block, module_identifier, period ;
    }

    Я не рискну сюда постить, потому что файл занимает почти 11 мегабайт.

Выводы

Пока рано...

PS. За Nitra.Visualizer спасибо прикольный инструмент, AST получены как раз им. По крайней мере в отличие от VS он не падает при попытке вставить весь файлик (13 Кб) с грамматикой, а пытается его разобрать и сожрав 1,5 Гб за 30 секунд бросает это занятие и говорит Unexpected token.

PS2. При попытке скопировать ошибку (с помощью контекстного меню) падает уже Nitra.Visualizer.

System.NullReferenceException was unhandled
Message: An unhandled exception of type 'System.NullReferenceException' occurred in Nitra.Visualizer.exe
Additional information: Ссылка на объект не указывает на экземпляр объекта.

в Nitra.Visualizer.MainWindow._errorsTreeView_CopyNodeText(Object sender, RoutedEventArgs e)
в System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
в System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
в System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
...

nitra
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.