稍微说明一点,整型常量和上面的标识符的词法,在调用lex.DefineToken时都多传了一个参数。这个参数是可选的描述信息,如果不传会直接使用正则表达式的字符串形式。而标识符的正则表达式有4万多个字符那么长而且没有可读性,所以加一个额外字符串描述一下。它将来会被用于生成编译错误信息。

最后我们来写空白符、换行符和注释的正则表达式。这三个是完全按照C# spec的规范编写的。其中注释包含了两种://开头直到换行的注释已经/*开头直到*/的多行注释。大家可以学习一下它们的正则表达式怎么写:

var RE_SpaceChar = RE.CharsOf(c => Char.GetUnicodeCategory(c) == UnicodeCategory.SpaceSeparator);

WHITESPACE = lex.DefineToken(RE_SpaceChar | RE.CharSet("\u0009\u000B\u000C"));

LINE_BREAKER = lex.DefineToken(
    RE.CharSet("\u000D\u000A\u0085\u2028\u2029") |
    RE.Literal("\r\n")
);

var RE_InputChar = RE.CharsOf(c => !"\u000D\u000A\u0085\u2028\u2029".Contains(c));
var RE_NotSlashOrAsterisk = RE.CharsOf(c => !"/*".Contains(c));
var RE_DelimitedCommentSection = RE.Symbol('/') | (RE.Symbol('*').Many() >> RE_NotSlashOrAsterisk);

COMMENT = lex.DefineToken(
    (RE.Literal("//") >> RE_InputChar.Many()) |
    (RE.Literal("/*") >> RE_DelimitedCommentSection.Many() >> RE.Symbol('*').Many1() >> RE.Symbol('/'))
);

最后还有一点后续的代码,从Lexicon对象生成ScannerInfo,再生成Scanner:

ScannerInfo info = lexicon.CreateScannerInfo();
Scanner scanner = new Scanner(info);

string source = "//任意miniSharp源代码";
StringReader sr = new StringReader(source);

scanner.SetSource(new SourceReader(sr));
scanner.SetSkipTokens(WHITESPACE.Index, LINE_BREAKER.Index, COMMENT.Index);

这样就完成了!我们创建了一个完整的miniSharp词法分析器。现在它就能分析所有miniSharp源代码了。注意我们设定了该词法分析器忽略所有空白符、换行以及注释,是为了后面语法分析简便而考虑的。各位读者可以自己试着任意扩展这个词法分析器,比如增加字符串常量的词法、更多关键字和运算符甚至前所未有的新词法。祝各位实践愉快!下一篇开始我们要进入另一个重要的环节——语法分析部分,敬请期待。

此外别忘了关注我的VBF项目:https://github.com/Ninputer/VBF 和我的微博:http://weibo.com/ninputer 多谢大家支持!

自己动手开发编译器(五)miniSharp语言的词法分析器的更多相关文章

  1. atitit.自己动手开发编译器and解释器(1) ------词法分析--attilax总结

    atitit.自己动手开发编译器and解释器(1) ------词法分析--attilax总结 1.   应用场景:::DSL 大大提升开发效率 1 2. 2. 流程如下::: 词法分析(生成toke ...

  2. atitit.自己动手开发编译器and解释器(2) ------语法分析,语义分析,代码生成--attilax总结

    atitit.自己动手开发编译器and解释器(2) ------语法分析,语义分析,代码生成--attilax总结 1. 建立AST 抽象语法树 Abstract Syntax Tree,AST) 1 ...

  3. 自己动手开发编译器(四)利用DFA转换表建立扫描器

    上回我们介绍了两种有穷自动机模型——确定性有穷自动机DFA和非确定性有穷自动机,以及从正则表达式经过NFA最终转化为DFA的算法.有些同学表示还是难以理解NFA到底怎么转化为DFA.所以本篇开头时我想 ...

  4. Android For JNI(五)——C语言多级指针,结构体,联合体,枚举,自定义类型

    Android For JNI(五)--C语言多级指针,结构体,联合体,枚举,自定义类型 我们的C已经渐渐的步入正轨了,基础过去之后,就是我们的NDK和JNI实战了 一.多级指针 指针的概念我们在前面 ...

  5. openresty 前端开发入门五之Mysql篇

    openresty 前端开发入门五之Mysql篇 这章主要演示怎么通过lua连接mysql,并根据用户输入的name从mysql获取数据,并返回给用户 操作mysql主要用到了lua-resty-my ...

  6. ASP.NET自定义控件组件开发 第五章 模板控件开发

    原文:ASP.NET自定义控件组件开发 第五章 模板控件开发 第五章 模板控件开发 系列文章链接: ASP.NET自定义控件组件开发 第一章 待续 ASP.NET自定义控件组件开发 第一章 第二篇 接 ...

  7. [原创].NET 分布式架构开发实战五 Framework改进篇

    原文:[原创].NET 分布式架构开发实战五 Framework改进篇 .NET 分布式架构开发实战五 Framework改进篇 前言:本来打算这篇文章来写DAL的重构的,现在计划有点改变.之前的文章 ...

  8. Django开发笔记五

    Django开发笔记一 Django开发笔记二 Django开发笔记三 Django开发笔记四 Django开发笔记五 Django开发笔记六 1.页面继承 定义base.html: <!DOC ...

  9. 带你从零学ReactNative开发跨平台App开发(五)

    ReactNative跨平台开发系列教程: 带你从零学ReactNative开发跨平台App开发(一) 带你从零学ReactNative开发跨平台App开发(二) 带你从零学ReactNative开发 ...

随机推荐

  1. SPFA 最短路径打印方法

    #include <iostream> #include <cstdlib> #include <cstdio> #include <algorithm> ...

  2. HBase Endpoint

    引言   假设HBase某张表有1000个Region,里面存储着100万行数据,现在需要统计满足某些条件的行数,普通的做法是使用Filter(过滤条件),通过HBase API将满足过滤条件的行数据 ...

  3. 解读sample1

    说明 理解被测试代码 理解测试代码 TEST宏 EXPECT_*断言和ASSERT_*断言 检查数值比较结果的断言 检查布尔值的断言 说明 被测试代码文件 sample1.h.sample1.cc 测 ...

  4. [Java] LinkedList / Queue - 源代码学习笔记

    简单地画了下 LinkedList 的继承关系,如下图.只是画了关注的部分,并不是完整的关系图.本博文涉及的是 Queue, Deque, LinkedList 的源代码阅读笔记.关于 List 接口 ...

  5. [Design Pattern] Adapter Pattern 简单案例

    Adapter Pattern, 即适配器模式,用于连接两个不兼容的接口,属于结构类的设计模式. 或者叫做,转换器模式. 下面是一个转换器模式简单案例. 假设已有 AudioPlayer 专门播放 m ...

  6. python_Opencv_滑动条用法

    前言: 创建一个简单的程序来说明滑动条用法:通过调节滑动条来设定画板颜色. 我们要创建一个窗口来显示显色,还有三个滑动条来设置B,G,R 的颜色. 当我们滑动滚动条是窗口的颜色也会发生相应改变. 默认 ...

  7. 用UBOOT自带loadb命令加载应用程序到SDRAM中运行的方法

    S3C44B0开发板中,用UBOOT自带loadb命令加载应用程序到SDRAM中运行的方法    1.开发板说明:  开发板上已有移植好的UBOOT运行.   2.交叉编译工具链为arm-linu-g ...

  8. yii2使用Gii生成代码

    本章节将介绍怎样使用 Gii 去自己主动生成 Web 网站经常使用功能的代码.使用 Gii 生成代码很easy,仅仅要依照 Gii 页面上的介绍输入正确的信息就可以. 贯穿本章节,你将会学到: 在你的 ...

  9. 你的第一个Windows程序——绘制窗口

    MSDN原文(英文) 绘制窗口 你已经创建了你的窗口,现在你想在它里面显示东西.在WIndows术语里,这就是所谓的绘制窗口.混合隐喻,一个窗口是一个空白画布,等待你去填充它. 有时你的程序将启动绘制 ...

  10. 百度——LBS.云 v2.0——创建自己的地理云数据

    随着云技术和地理信息(GIS)技术的发展,今年终于进入了.地理分享的新纪元.百度提供了LBS的云存储.真是个不错的功能.下面让我们来看看如何使用吧. 1.注册百度开发者账号(此处略去88个字) 2.创 ...