关于golang:使用BKLexer进行词法分析

10次阅读

共计 2208 个字符,预计需要花费 6 分钟才能阅读完成。

前几天我曾经封装好了词法分析器并命名 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》,欢送关注。

正文完
 0