用C#实现一个Json解析器(4)——词法分析器

本文详细介绍了如何使用C#实现一个Json解析器的词法分析器部分,包括单词类和词性的定义,词法分析器类的实现,以及基于有限状态机的状态转换逻辑。通过分析每个状态的行为,如构造符、字面量、数字和字符串状态,阐述了词法分析器的工作原理。
摘要由CSDN通过智能技术生成

前言

本次我们实现解析器的词法分析功能。

注意:示例代码使用了C#8.0的语法特性,如果要在你的机器上运行,请确保安装了.Net Core 3.x开发环境。

单词类和词性类

词法分析器输出的是单词流,所以先要有单词类。这里有三点需要声明:

  1. 单词这种轻量级对象,直接将其声明成结构体能让它们在内存中连续分布,并且不用消耗额外空间生成引用变量。
  2. 我们不需要修改单词变量,因此直接声明为只读结构。
  3. 属性的本质是方法,需要切换上下文。为了提高性能,我们直接使用公有字段。
internal readonly struct Token
{
   
	
    public readonly TokenType type;
    public readonly string value;
    
    public Token(TokenType type) => (this.type, value) = (type, null);
    public Token(TokenType type, string value) => (this.type, this.value) = (type, value);
    
}

在单词类的定义中有一个TokenType字段,这是一个枚举类,表示单词的词性。

[Flags]
internal enum TokenType
{
   
    None = 0x0,
    ObjectStart = 0x1,
    ObjectEnd = 0x2,
    ArrayStart = 0x4,
    ArrayEnd = 0x8,
    Colon = 0x10,
    Comma = 0x20,
    Number = 0x40,
    String = 0x80,
    True = 0x100,
    False = 0x200,
    Null = 0x400,
    End = 0x800
}

词法分析器类

有了单词类,我们就可以着手实现词法分析器了。词法分析器是一个静态类,其核心是Analyze方法:

public static Queue<Token> Analyze(string json)
{
   
    ...
}

返回值是一个由Token构成的队列,这种数据结构能简化语法分析器读取单词的代码。

有限状态机

词法分析器基于有限状态机实现,每次读取json字符串中的一个字符,根据读到的内容进行单词转换、状态转换等逻辑。词法分析器的状态转换图如下:
状态转换图
下面分析每个状态中执行的逻辑:

  1. 就绪:读取下一字符,根据读取到的内容转换状态。
  2. 构造符:将对应的构造符单词加到队尾,回到就绪状态。
  3. 字面量:如果读到的是t,就向下读三个字符,若读完为true则将true单词加到队尾,回到就绪状态,否则抛出异常。false和null同理。
  4. 数字:一直读直到读到逗号或-1,并将每次读到的结果存入一个字符串中,将结果与一个表示数字的模式匹配,若匹配则将对应的数字单词加入队尾,回到就绪状态,否则抛出异常。
  5. 字符串:一直读直到读到双引号("不算),并将每次读到的结果存入一个字符串中,将对应的字符串单词加入队尾,回到就绪状态。
  6. 终止:向队尾加入终止单词,结束流程。

对应方法

我们将就绪和终止的逻辑放在Analyze方法中,将其余每个状态的逻辑放入不同的私有方法中,增强代码的可读性。

就绪和终止状态
        public static Queue<Token> Analyze(string json)
        {
   
            var tokens = new Queue<Token>();
            // 清除空白字符
            json = json.Replace(" ", "")
                       .Replace("\t", "")
                       .Replace("\n", "")
                       .Replace("\f", "")
                       .Replace
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值