Попытка построить грамматику C # для bison / wisent

Я никогда раньше не работал над Bison или Wisent.
с чего начать?

Моя настоящая цель - создать рабочую грамматику Wisent / Semantic для C #, чтобы можно было редактировать C # в emacs с автозавершением кода и всем остальным CEDET вкусности. (Для тех, кто не знает, Wisent - это порт на emacs-lisp для GNU Bison, который включен в CEDET. The Wisent, по всей видимости, является европейским бизоном. А бизон, насколько я понимаю, представляет собой игру слов, заимствованную из YACC. А CEDET - это набор инструментов разработки Emacs. Все поняли? Я не буду пытаться определять emacs.)

Microsoft предоставляет грамматику BNF для C #, включая все расширения LINQ, в справочный документ по языку. Мне удалось перевести это в файл .wy, который успешно компилируется с semantic-grammar-create-package.

Но скомпилированная грамматика не «работает». В некоторых случаях грамматика «находит» enum объявления, но не class объявления. Почему? Я не знаю. Мне не удалось заставить его распознавать атрибуты. Я не считаю "отладку" грамматики очень простой.

Я подумал, что сделаю шаг назад и попытаюсь создать мудрую грамматику для гораздо более простого языка, игрушечного языка всего с несколькими ключевыми словами. Просто чтобы набраться опыта. Даже это оказывается проблемой.

Я видел документы .info по грамматике fw и wisent, но ... все же эти вещи не совсем проясняют для меня, как это работает на самом деле.

So

Q1: какие-нибудь советы по отладке грамматики Wisent в emacs? Есть ли способ запустить "похожий на ворс" элемент грамматики, чтобы узнать, есть ли неиспользуемые правила и подобные тупики? А как насчет возможности наблюдать за работой парсера? Что-нибудь в этом роде?

Q2. Какие-нибудь советы по освоению зубров и зубров в целом? Я думаю, что это инструмент, который позволит мне получить некоторое представление о том, как работают правила. Что-то, что обеспечивает некоторую прозрачность, вместо того, чтобы испытывать «это не сработало», которое я получаю сейчас с Wisent.

Q3. Следует ли мне сдаться и стать органическим фермером, вместо того чтобы продолжать бороться с этим?


ps: Я знаю о существующей грамматике C # в каталоге contrib файла CEDET / semantic. Эта штука работает, но ... Она не поддерживает последнюю спецификацию C #, включая LINQ, частичные классы и методы, yield, анонимные методы, инициализаторы объектов и так далее. Также он в основном занимается парсингом кучи кода C #. Он вынюхивает классы и методы, а затем выходит из строя. Даже циклы foreach выполняются не совсем правильно. В общем, это хорошо, но я бы хотел, чтобы он стал лучше. Я пытаюсь сделать его актуальным, а также расширить его для синтаксического анализа кода C #.


person Cheeso    schedule 04.06.2010    source источник


Ответы (2)


Вы можете посмотреть пример calc в каталоге semantic / wisent. Это довольно просто, а также показывает, как использовать функции% left и% right. Он будет «выполнять» код вместо того, чтобы преобразовывать его в теги. Некоторые другие простые грамматики включают синтаксический анализатор точек в cogre и синтаксический анализатор srecode в srecode.

Для быстрой отладки в меню есть флажок подробности, хотя, честно говоря, я его не пробовал. Также существует wisent-debug-on-entry, которая позволяет вам выбрать действие, которое заставит отладчик Emacs останавливаться в этом действии, чтобы вы могли видеть значения.

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

person Eric    schedule 05.06.2010

Относительно Q1: 1-й убедитесь, что действительно используется wisent parser:

(fetch-overload 'semantic-parse-stream)

должен вернуть wisent-parse-stream.

Запустите следующий elisp-snippet:

(easy-menu-add-item semantic-mode-map '(menu-bar cedet-menu) ["Wisent-Debug" wisent-debug-toggle :style toggle :selected (wisent-debug-active)])
(defun wisent-debug-active ()
  "Return non-nil if wisent debugging is active."
  (assoc 'wisent-parse-action-debug (ad-get-advice-info-field 'wisent-parse-action 'after)))
(defun wisent-debug-toggle ()
  "Install debugging of wisent-parser"
  (interactive)
  (if (wisent-debug-active)
      (ad-unadvise 'wisent-parse-action)
    (defadvice wisent-parse-action (after wisent-parse-action-debug activate)
      (princ (format "\ntoken:%S;\nactionList:%S;\nreturn:%S\n"
             (eval i)
             (eval al)
             (eval ad-return-value)) (get-buffer-create "*wisent-debug*"))))
  (let ((fileName (locate-file "semantic/wisent/wisent" load-path '(".el" ".el.gz")))
    fct found)
    (if fileName
    (with-current-buffer (find-file-noselect fileName)
      (goto-char (point-max))
      (while (progn
           (backward-list)
           (setq fct (sexp-at-point))
           (null
            (or
             (bobp)
             (and
              (listp fct)
              (eq 'defun (car fct))
              (setq found (eq 'wisent-parse (cadr fct))))))))
      (if found
          (eval fct)
        (error "Did not find wisent-parse.")))
      (error "Source file for semantic/wisent/wisent not found.")
      )))

Он создает новую запись Wisent-Debug в меню разработки. Щелчок по этой записи переключает отладку парсера wisent. В следующий раз, когда вы повторно проанализируете буфер с помощью wisent-parser, он выведет отладочную информацию в буфер * wisent debug *. Буфер * wisent debug * не отображается автоматически, но вы можете найти его через меню буфера. Чтобы избежать переполнения * wisent debug *, вы должны отключить «Повторную обработку при простое». Время от времени вы должны очищать буфер * wisent debug * с помощью erase-buffer.

person Tobias    schedule 04.09.2013