2010-06-04 66 views
11

我从来没有做过Bison或Wisent之前。
我该如何开始?试图为Bison/wisent构建C#语法

我的真正目标是为C#生成一个可用的Wisent/Semantic语法,允许C#在代码完成时在emacs中编辑,以及所有其他CEDET好东西。 (对于那些不知道的人来说,Wisent是一个Emacs-lisp端口GNU Bison,它包含在CEDET中,The Wisent显然是欧洲野牛,而我认为Bison是从YACC衍生而来的玩意儿。而且CEDET是Emacs开发工具的集合,所有这些都被抓住了吗?我不打算试着定义emacs。)

Microsoft为language reference document中的C#提供BNF语法,包括所有LINQ扩展。我可以将它翻译成一个.wy文件,该文件通过semantic-grammar-create-package编译成功。

但编译的语法不“工作”。在某些情况下,语法“发现”声明enum,但不声明class。为什么?我不知道。我一直无法识别属性。 我没有发现语法的“调试”非常简单。

我以为我会退后一步,尝试为一种极其简单的语言(一种只有少数关键字的玩具语言)编写一个明智的语法。只是为了获得一些经验。即使这也是一个挑战。

我已经看到了关于语法fw和wisent的.info文档,但是......仍然那些东西对我来说并没有真正澄清,这些东西真的有效。

所以

Q1:关于调试在Emacs一个野牛之语法任何提示?有没有办法在语法上运行“类似皮棉”的东西来查明是否有未使用的规则,死胡同这样的东西?怎样才能观察解析器的行动?任何这样的事情?

Q2:关于提高野牛/智能一般速度的任何提示?我在想的是一个工具,可以让我深入了解这些规则是如何工作的。一些提供一些透明度的东西,而不是我现在用Wisent获得的“它没用”的体验。

Q3:我应该放弃并成为一名有机农民,而不是继续与之抗争?


ps:我知道CEDET /语义的contrib目录中现有的C#语法。这件事很有效,但是......它不支持最新的C#规范,包括LINQ,部分类和方法,yield,匿名方法,对象初始值设定项等等。此外,它主要用于解析一堆C#代码。它嗅出类和方法,然后退出。即使是foreach循环也没有完全正确。尽管如此,但我希望看到它会更好。我想要做的就是使其成为最新的,并且扩展它来解析更多的C#代码。

回答

4

您可能想看看语义/ wisent目录中的calc例子。它非常简单,并且还显示了如何使用%左和右右特征。它将“执行”代码而不是将其转换为标签。其他一些简单的语法包括cogre中的'点'分析器和srecode中的srecode分析器。

为了明智的调试,菜单中有一个冗长的标志,尽管说实话我没有尝试过。还有一个是wisent-debug-on-entry,它可以让你选择一个动作,使得Emacs调试器在该动作中停止,这样你就可以看到这些值是什么。

较旧的“牛”解析器有一个调试模式,允许您逐步执行规则,但它从未移植到智能。当我编写智能解析器时,这是一个我非常想念的功能。

2

关于Q1: 1确保野牛之解析器实际使用:

(fetch-overload 'semantic-parse-stream) 

应该返回wisent-parse-stream

运行下面的elisp - 摘录:

(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-parser重新分析缓冲区时,它将调试信息输出到缓冲区* wisent debug *。缓冲区*智能调试*不会自动显示,但您可以通过缓冲区菜单找到它。 为了避免* wisent调试*泛滥,你应该禁用“空闲时重新分配”。 有时你会用擦除缓冲区清除缓冲区*智能调试*。