我正在考虑利用一些业余时间来设计和实施正规语言和自动机理论课程的教学工具。我正在尝试确定OOP的实施是否合适,如果是的话,是否有人可以建议对我在下面概述的设计进行高级改进。
语言分析中揭示了许多潜在的课程。一些(如果我错过了任何根本的话,请告诉我)是:语法;非终结;终奌站;生产;常规语法;无上下文语法;上下文敏感语法;不受限制的语法;自动机;州;符号;过渡; DFA; NFA; NFA-LAMBDA; DPDA; PDA; LBA;图灵机。
问题1:每种语法是否应该在实现中获得自己的类,或者是否应该使用过多的语法类来确定它是什么类型的语法(例如,“isRegular()”,“ isContextFree()“等等。” (更一般地说,应该只在域模型中有所不同的类,并且只在行为方面,通过实现中的继承来表示,或者它是否更好简单地将不同类型的行为推送到父类中?)
问题2:“符号”,“状态”,“非终结”等内容应该在实现中获得自己的类,还是应该由其容器控制? (更一般地说,域模型中的非常简单的类应该在实现中给出它们自己的类 - 例如,为了可扩展性 - 还是应该将它们推入容器类?)
问题3:在实现中,Transition应该是它自己的类吗?如果是这样的话,我需要将它子类化以支持每种类型的自动机(因为除了状态方面不同之外,它们也是在过渡期间会发生什么不同? (更一般地说,有两个抽象的父类是很好的做法,其中一个孩子和另一个孩子之间存在双生子... ?)
我意识到,在一天结束时,很多这些决定只是设计决策,但我想知道你们对OOP设计中的最佳实践的看法。而且,我不仅仅将“更普遍”的问题作为纯粹的OOP设计问题提出的原因是,我希望从具有这种领域(语言和自动机)经验的人那里获得特殊的观点。
非常感谢任何帮助。
答案 0 :(得分:2)
好主意。完成类似的东西,首先是程序编程,首先是O.O.,稍后。
回答1:两者。一些语法或标记将具有特定的方法或属性,而其他语法或标记应在所有语法之间共享。
答案2:他们应该有自己的课程,altought可以分享共同的祖先。
答案3:可以双向处理,定义特定类的altought可能很有用。我同意存在其他类/对象之间的交集或关联,但是,它们很难建模。 “代理”设计模式就是一个例子。
使用LEX,Bison,yacc进行教学语言设计很困难。我“听说”ANTLR是一个很好的设计工具,用于教授编译器相关的东西。
你想做什么?
面向对象的解析器/扫描器?
已经有一些,我无法理解如何使用它们。他们中的一些人声明了新的语法,比如定义新的类,但在这种情况下,我发现函数式编程(语法)或逻辑编程(语法)更适合于声明规则。
视觉相关工具:
http://www.ust-solutions.com/ultragram.aspx
http://antlr.org/works/index.html
祝你好运; - )
答案 1 :(得分:2)
更一般地说,如果在域模型中只有一点点不同的类,并且只在行为方面有所不同,那么在实现中通过继承表示,...
行为不是“唯一的”。行为是对象最重要的部分。
或者简单地将不同类型的行为推送到父类中是否更好?
当然不是。这将违反Liskov替代原则 继承不应该用于“更容易访问常见的东西”。
父母班级的内容在儿童班级中完全无处不在,如果孩子不遵守,则避免继承和使用作文。
更一般地说,域模型中的非常简单的类是否应该在实现中给出它们自己的类 - 例如为了可扩展性 - 还是应该将其推入容器类?
这取决于你的逻辑将如何“深入”。
通常只有在达到某些限制时才开始分解是个好主意 有人称之为进化设计。
E.g。 - 我有“类不能大于〜200行代码”,“对象不得与超过5-7个其他对象交谈”,“方法不应大于~10行代码”,“同样的逻辑应该只写一次“等......
此外 - 很容易低估语义。 if order.isOverdue()
比if order.dueDate<date.Now()
更容易理解和理解{{1}}。引入反映域概念的类极大地“人性化”代码 - 提高抽象级别(想想“asm vs java”)。
但是为了分解而进行分解会导致不必要的复杂性 它必须是合理的。
在实现过程中,Transition应该是它自己的类,如果是这样的话,我需要将它子类化以支持每种类型的自动机(因为除了状态不同之外,它们在发生的事情方面也有所不同过渡期间??
只要它符合您的域名,就没有任何问题。
抽象的创建是高度依赖于您的领域的艺术活动(例如,如果要求您的代码被视为课程的教学工具被遗忘,那么正式语言和自动化专家的建议可能会严重过于复杂)。
答案 2 :(得分:2)
如果你想使用现有的解决方案而不是写一个解决方案,我在NCSU的一些朋友写了一个名为ProofChecker的工具,可能符合这个要求。
它是用Java编写的,因此也可以满足你的OO角度。