Oop 在构建lexer/scanner时,如何使用面向对象的设计范式?

Oop 在构建lexer/scanner时,如何使用面向对象的设计范式?,oop,architecture,smalltalk,lexer,Oop,Architecture,Smalltalk,Lexer,我正在尝试设计一个小型正则表达式引擎(在Smalltalk中),以帮助提高我的面向对象技能 我用其他语言(以及Smalltalk原生语言)研究了一些正则表达式引擎,它们似乎都有一个单独的“Lexer”或“Scanner”类。这让我感到困惑,因为我认为lexer是一个单一的函数,它应该将模式作为输入(可能是一个“语法”对象,它定义令牌类型),并返回令牌流。我很难弄清楚接口将具有哪些额外功能,以及对象需要保持哪些额外状态 如何将其分解为面向对象的设计? 我应该补充一点,当我阅读源代码时,我似乎经常看

我正在尝试设计一个小型正则表达式引擎(在Smalltalk中),以帮助提高我的面向对象技能

我用其他语言(以及Smalltalk原生语言)研究了一些正则表达式引擎,它们似乎都有一个单独的“Lexer”或“Scanner”类。这让我感到困惑,因为我认为lexer是一个单一的函数,它应该将模式作为输入(可能是一个“语法”对象,它定义令牌类型),并返回令牌流。我很难弄清楚接口将具有哪些额外功能,以及对象需要保持哪些额外状态

如何将其分解为面向对象的设计?
我应该补充一点,当我阅读源代码时,我似乎经常看到这一点:一个在名称末尾添加了动词+“er”的类。这似乎与“干净的代码”和“完整的代码”等书所教的“正确的面向对象设计”背道而驰

这是一个非常宽泛的问题,所以我们只能给你同样宽泛的答案。这是我的

在考虑面向对象时,我们试图在数据和行为之间建立明确的区别。一个对象同时具有这两个属性,一般来说,行为与数据越独立越好

这些基本的指导原则并不总能使设计看起来自然。原因是,有时我们倾向于将与某些数据相关的行为附加到非常相同的数据上。这可能会隐藏应该拥有这种行为的实际对象

这种现象的一个典型例子是算法。我们有一些数据:算法输入和一些行为:算法输出,并且认为这些行为应该附加到数据中。因此,我们很难将其作为上述数据的函数来实现

然而,在大多数情况下,这种简单化的方法是有问题的。例如,许多算法可能会产生多个输出。以两个多项式的除法为例,其中输出为商和余数。即使算法生成一个输出,我们可能会询问它需要多长时间,甚至告诉它取消执行并停止自己,等等

由于这些原因(以及其他类似的原因),将算法视为对象而不是函数总是可取的。这样一个对象的实例变量通常会引用

inputs        - "one or more depending on the algorithm"
outputs       - "idem"
auxiliary     - "for holding the algorithm internal state while running"
progress      - "for recording degree of advancement"
state         - "various uses"
将算法实现为对象将有助于添加以下功能:

  • 使用不同的输入重用同一实例
  • 有保存输出的地方
  • 向用户提供反馈
  • 告诉算法取消并停止执行(通过将其状态设置为
    #cancel
  • 计算迭代次数并为调试注册其他内容

  • 如您所见,作为对象的算法比作为函数的算法丰富得多。这并不意味着您必须放弃功能性方法。只需具体化算法,让您的客户端对象提供一个函数,该函数将使用该算法并返回与该上下文相关的结果。

    从名称Lexer/Scanner/Parser/Compiler/中可以清楚看出。。。我们正在具体化一个函数。但请记住,在Smalltalk中,没有任何功能。只有对象和消息

    当然,脑海中浮现的明显目标是:

    • 无论是什么节点组成了你将要产生的树状结构
    • 如果你想有一个中间的Lexer
    • 语法本身(更高级)
    但是,字符流到任何树状结构的转换将在哪里发生呢

    在这种情况下,Leandro的回答反映了一些常见的做法。将算法具体化,例如错误处理、交互式显示和错误纠正等,这是很好的,但可能会导致或多或少的单片实现必须明确地处理自动机的状态,这对函数式语言爱好者来说并没有多大吸引力


    首先自己尝试一下,但一旦你取得了足够的进步,我强烈建议你学习PetitPasser,在这里做一个介绍。你会发现语法本身,或者更确切地说是构成语法的节点,可以充当解析器,从而分解为基本、简单、优雅和可组合的对象。

    如果你对Smalltalk感兴趣,我强烈建议你至少读一本关于这个主题的好书。一个例子是肯特·贝克(Kent Beck)。