使用BKLexer进行词法分析


本文摘自网络,作者,侵删。

前几天我已经封装好了词法分析器并命名BKLexer,当前BKLexer分别支持Go/C++/Python。

程序代码放在Github项目当中: 点进项目页

可以参考每一个版本的try_lexer代码进行学习,下面以Go为例:

package main

import (
    "fmt"
    "strconv"
    "./bklexer"
)

func main() {
    fmt.Println("Test Code:")
    code := "声明 变量 = PI * 100 - fda\n1024 * 4 * 3.14 ### \n123"
    fmt.Println(code)
    fmt.Println("--------------------------------")

    lexer := BKLexer.NewLexer()
    lexer.AddRule("\\d+\\.\\d*", "FLOAT")
    lexer.AddRule("\\d+", "INT")
    lexer.AddRule("[\\p{L}\\d_]+", "NAME")
    lexer.AddRule("\\+", "PLUS")
    lexer.AddRule("\\-", "MINUS")
    lexer.AddRule("\\*", "MUL")
    lexer.AddRule("/", "DIV")
    lexer.AddRule("=", "ASSIGN")
    lexer.AddRule("#[^\\r\\n]*", "COMMENT")
    lexer.AddIgnores("[ \\f\\t]+")

    lexer.Build(code)
    for true {
        token := lexer.NextToken()
        if (token.TType != BKLexer.TOKEN_TYPE_EOF) {
            fmt.Printf("%s\t%s\tt%d\t%d\t%d,%d\n",
            token.Name, strconv.Quote(token.Source), token.TType, token.Position, token.Row, token.Col)
        }
        if (token.TType == BKLexer.TOKEN_TYPE_EOF || token.TType == BKLexer.TOKEN_TYPE_ERROR) {
            break
        }
    }
}

首先引入bklexer在内的包

import (
    "fmt"
    "strconv"
    "./bklexer"
)
  • fmt 用于打印输出
  • strconv 用于优化字面量的显示
  • ./bklexer 引入BKLexer包

实例化词法分析器并设定规则

lexer := BKLexer.NewLexer()
lexer.AddRule("\\d+\\.\\d*", "FLOAT")
lexer.AddRule("\\d+", "INT")
lexer.AddRule("[\\p{L}\\d_]+", "NAME")
lexer.AddRule("\\+", "PLUS")
lexer.AddRule("\\-", "MINUS")
lexer.AddRule("\\*", "MUL")
lexer.AddRule("/", "DIV")
lexer.AddRule("=", "ASSIGN")
lexer.AddRule("#[^\\r\\n]*", "COMMENT")
lexer.AddIgnores("[ \\f\\t]+")
  • NewLexer 实例化词法分析器
  • AddRule 增加匹配规则,参数分别为正则表达式,对应的类型名称
  • AddIgnores 用于设定需要忽略的字符内容

构建并循环匹配

lexer.Build(code)
for true {
    token := lexer.NextToken()
    if (token.TType != BKLexer.TOKEN_TYPE_EOF) {
        fmt.Printf("%s\t%s\tt%d\t%d\t%d,%d\n",
        token.Name, strconv.Quote(token.Source), token.TType, token.Position, token.Row, token.Col)
    }
    if (token.TType == BKLexer.TOKEN_TYPE_EOF || token.TType == BKLexer.TOKEN_TYPE_ERROR) {
        break
    }
}

使用Build方法,将代码code作为参数进行构建,然后循环调用NextToken方法获得下一个Token,并打印相关信息。
需要注意的是应当对Token的类型进行检测判断是否为EOFERROR以决定是否终止。

运行结果如下

Test Code:
声明 变量 = PI * 100 - fda
1024 * 4 * 3.14 ### 
123
--------------------------------
NAME    "声明"    t3    0    0,0
NAME    "变量"    t3    7    0,3
ASSIGN    "="        t8    14    0,6
NAME    "PI"    t3    16    0,8
MUL        "*"        t6    19    0,11
INT        "100"    t2    21    0,13
MINUS    "-"        t5    25    0,17
NAME    "fda"    t3    27    0,19
NEWLINE    "\n"    t0    30    0,22
INT        "1024"    t2    31    1,0
MUL        "*"        t6    36    1,5
INT        "4"        t2    38    1,7
MUL        "*"        t6    40    1,9
FLOAT    "3.14"    t1    42    1,11
COMMENT    "### "    t9    47    1,16
NEWLINE    "\n"    t0    51    1,20
INT        "123"    t2    52    2,0

下篇《递归向下算法实现Calc》,欢迎关注。


本文来自:Segmentfault

感谢作者:bxtkezhan

查看原文:使用BKLexer进行词法分析

相关阅读 >>

Golang main如何返回值

Go1.4 bootstrap 源码安装新版Go

手撸Golang 基本数据结构与算法 归并排序

Golang组件化网络服务器框架halia指南

聊一聊Golang的协程

Go的声明语法为什么是这样

Gocn酷Go推荐】Goroutine 泄漏防治神器 Goleak

16 Golang结构体详解(二)

Golang判断是文件还是文件夹

beeGo项目和Go项目 打包部署到linux

更多相关阅读请进入《Go》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...