前几天我曾经封装好了词法分析器并命名BKLexer,以后BKLexer别离反对Go/C++/Python。

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

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

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

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