C++抽象编程——面向对象(9)——token扫描器

token扫描器(Designing a token scanner class)

在字符串系列中,最为复杂的字符串处理示例是Pig Latin转换了。 (链接C++抽象编程——字符串(4)——回文数的检查与Pig Latin游戏)PigLatin程序将问题分解为两个阶段:lineToPigLatin函数将输入划分为单词,然后调用wordToPigLatin将每个单词转换为Pig Latin的句子。然而,这种分解的第一阶段并不完全是在Pig Latin这里特有的。许多应用程序需要将字符串划分为单词,或更一般地将其划分为大于单个字符的逻辑单元。 在计算机科学中,这样的单元通常称为token(这个单词我真的不知道怎么翻译,有人称为令牌)。
鉴于将字符串划分为单独的token的问题在应用程序中频繁出现,构建一个负责该任务的库包是有用的。 这次我们介绍为此目的设计的TokenScanner类。主要目标是构建一个易于使用的软件包,但仍具有足够的灵活性以满足各种客户端的需求。

客户端想从token扫描器得到什么

和往常一样,开始设计TokenScanner类的最好方法是从客户端的角度来看问题。想要使用扫描仪的每个客户端都会以token的来源为开头,这可能是字符串,但也可能是从文件读取数据的应用程序的输入流。 在这两种情况下,客户端需要的方法是从该来源开始检索单个token。设计提供必要功能的TokenScanner类有几种策略。例如,我们可以使token扫描器返回包含整个token列表的vector。但是,该策略不适用于使用大型输入文件的应用程序,因为扫描程序必须创建包含整个token列表的单个vector。 更节省空间的方法是让扫描仪一次提供一个token。 您使用此设计时,从扫描仪读取令牌的过程可以用下面的伪代码表示:

Set the input for the token scanner to be some string or input stream.
while (more tokens are available) {
Read the next token.
}

为token扫描器设置输入,当其他的tokens可以用的时候,我们读取下一个token。
该伪代码结构立即提示了TokenScanner类必须支持的方法。 从这个例子可以看出,TokenScanner可以导出以下方法:

  • setInput方法:允许客户端指定token源。为了最大的灵活性,该方法应该被重载,以将字符串或输入流作为参数
  • hasMoreTokens方法:用来测试token扫描器是否有更多的token待处理
  • nextToken方法: 用于扫描并返回下一个token。

这些方法定义了令牌扫描器的操作结构,并且在很大程度上独立于应用程序的细节。然而,不同的应用程序以各种不同的方式定义token,这意味着TokenScanner类必须给客户端一些提示或者方式控制哪些类型的token,以便它被识别。
回到PigLatin,如果用使用token扫描器重写PigLatin程序,我们就不能忽略空格和标点符号,因为这些字符需要是输出的一部分。在这个问题的背景下,token分为两类:
1. 一串连续的字母数字字符,代表一个字。(A string of consecutive alphanumeric characters representing a word
2. 由空格或标点符号组成的单字符串。(A single-character string consisting of a space or punctuation mark.

举个例子,如果你输入的是下面的句子:

this is "pig latin"

调用nextToken将返回以下9个tokens的序列:

然而,其他应用程序可能会以不同的方式定义token。例如,您的C++编译器使用令牌扫描程序将程序中断到编程语境中有意义的令牌,包括标识符,常量,运算符以及定义语言句法结构的其他符号。 例如,如果给编译器的token扫描器下面这一行:

cout << "hello, world" << endl;

您希望提供以下token序列如下:

这里跟上面不同,hello world作为了整体。token的定义中这两个应用程序之间存在一些差异。 在Pig Latin中,任何不是字母数字字符序列的任何内容都将返回为单字符token。在编译器的例子中,情况比较复杂。一方面,编程语言通常定义多个字符运算符,如 << 必须被视为单个token。类似地,字符串常量“hello,world”只有在令牌扫描器将其视为单个实体时才具有正确的含义。编译器的token扫描器会完全忽略输入空格,除非它们出现在字符串常量中。
如果您继续在编译器上学习class,可以构建一个token扫描器,允许客户端通过提供一组精确的规则来指定什么构成特定的token。 然而,这种普遍性往往以牺牲简单性为代价。 如果强制客户指定token形成的规则,则需要学习如何编写这些规则,这在很多方面与学习新语言相似。 更糟糕的是,令牌形成的规则,特别是如果你试图指定一个编译器用来识别数字的规则,这对于客户来说是很困难的。
如果你在接口中的目标是最大限度地简化,那么设计TokenScanner类可能更好,以便客户端可以启用特定的选项,使其能够识别在特定应用程序上下文中使用的令牌类型。 如果您想要的是token扫描器,可以将连续的字母数字字符收集到单词中,那么可以在最简单的配置中使用TokenScanner类。如果想要让TokenScanner识别C++程序中的单位,则可以启用说明扫描仪的选项,例如忽略空格,将引用的字符串视为单个单位,并且标点符号的某些组合表示多字符运算符。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MICROSOFT FOUNDATION CLASS LIBRARY : ZSCPascal AppWizard has created this ZSCPascal application for you. This application not only demonstrates the basics of using the Microsoft Foundation classes but is also a starting point for writing your application. This file contains a summary of what you will find in each of the files that make up your ZSCPascal application. ZSCPascal.h This is the main header file for the application. It includes other project specific headers (including Resource.h) and declares the CZSCPascalApp application class. ZSCPascal.cpp This is the main application source file that contains the application class CZSCPascalApp. ZSCPascal.rc This is a listing of all of the Microsoft Windows resources that the program uses. It includes the icons, bitmaps, and cursors that are stored in the RES subdirectory. This file can be directly edited in Microsoft Developer Studio. resSCPascal.ico This is an icon file, which is used as the application s icon. This icon is included by the main resource file ZSCPascal.rc. resSCPascal.rc2 This file contains resources that are not edited by Microsoft Developer Studio. You should place all resources not editable by the resource editor in this file. ZSCPascal.reg This is an example .REG file that shows you the kind of registration settings the framework will set for you. You can use this as a .REG file to go along with your application or just delete it and rely on the default RegisterShellFileTypes registration. ZSCPascal.clw This file contains information used by ClassWizard to edit existing classes or add new classes. ClassWizard also uses this file to store information needed to create and edit message maps and dialog data maps and to create prototype member functions. For the main frame window: MainFrm.h, MainFrm.cpp These files contain the frame class CMainFrame, which is derived from CMDIFrameWnd and controls all MDI frame features. resToolbar.bmp This bitmap file is used to create tiled images for the toolbar. The initial toolbar and status bar are constructed in the CMainFrame class. Edit this toolbar bitmap along with the array in MainFrm.cpp to add more toolbar buttons. AppWizard creates one document type and one view: ZSCPascalDoc.h, ZSCPascalDoc.cpp - the document These files contain your CZSCPascalDoc class. Edit these files to add your special document data and to implement file saving and loading (via CZSCPascalDoc::Serialize). ZSCPascalView.h, ZSCPascalView.cpp - the view of the document These files contain your CZSCPascalView class. CZSCPascalView objects are used to view CZSCPascalDoc objects. resSCPascalDoc.ico This is an icon file, which is used as the icon for MDI child windows for the CZSCPascalDoc class. This icon is included by the main resource file ZSCPascal.rc. Other standard files: StdAfx.h, StdAfx.cpp These files are used to build a precompiled header (PCH) file named ZSCPascal.pch and a precompiled types file named StdAfx.obj. Resource.h This is the standard header file, which defines new resource IDs. Microsoft Developer Studio reads and updates this file. Other notes: AppWizard uses "TODO:" to indicate parts of the source code you should add to or customize. If your application uses MFC in a shared DLL, and your application is in a language other than the operating system s current language, you will need to copy the corresponding localized resources MFC40XXX.DLL from the Microsoft Visual C++ CD-ROM onto the system or system32 directory, and rename it to be MFCLOC.DLL. ("XXX" stands for the language abbreviation. For example, MFC40DEU.DLL contains resources translated to German.) If you don t do this, some of the UI elements of your application will remain in the language of the operating system.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值