前言 Lexer词法分析器,是将原始字符串转换为有意义的标记的过程。 一、词法标记类型定义 通过定义types变量,定义了普通字符串、运算符、关键字、逻辑运算符等类型。
Lexer是什么 Lexer是Lexical analyzer的缩写,中文意思为词法分析器,是进行词法分析的程序或者函数,这也是编译器所做的第一项工作。 Lexer的实现 从这里开始,将会开始进行第一步,也就是实现一个简单的词法分析器,文章中只会讲述思想的思路以及部分代码,完整的代码请看我的github:h1J4cker 我们先思考一下,在我们的代码中,
目前先改到这里了 相关前置知识 之后的内容开始设计lexer和parser。假设读者没有相关知识,我先来大概讲一下编译器从源码生成到ast的流程。 手写的灵活性灵活度是会比生成器要高的,但是相对比较复杂 关于手写方式有一种叫parser combaintor的技术,能够通过组合不同的函数来实现解析,实现起来自然是比传统的手写方式方便,而我这里选择的也正是这种方案 Lexer 对于我之前lexer和parser混在一起写的做法处理这样的情况是非常难的。
. */ func BeginLexing(name, input string) *lexer.Lexer { l := &lexer.Lexer{ Name: name, . */ func LexBegin(lexer *Lexer) LexFn { lexer.SkipWhitespace() if strings.HasPrefix(lexer.InputToEnd (lexer *Lexer) LexFn { for { if lexer.IsEOF() { return lexer.Errorf(errors.LEXER_ERROR_MISSING_RIGHT_BRACKET (lexer *Lexer) LexFn { lexer.Pos += len(lexertoken.RIGHT_BRACKET) lexer.Emit(lexertoken.TOKEN_RIGHT_BRACKET (lexer *Lexer) LexFn { lexer.Pos += len(lexertoken.EQUAL_SIGN) lexer.Emit(lexertoken.EQUAL_SIGN
(lexer.TRUE) true_type := NewType("bool", lexer.TRUE, 1) return NewConstant(0, &tok, true_type (1, lexer.NewTokenWithString(lexer.ID, "a"), expr_type) id_b := inter.NewID(1, lexer.NewTokenWithString (lexer.ID, "b"), expr_type) //a+b arith1, _ := inter.NewArith(1, lexer.NewTokenWithString(lexer.PLUS (1, lexer.NewTokenWithString(lexer.PLUS, "+"), id_c, id_d) arith3, _ := inter.NewArith(1, lexer.NewTokenWithString = inter.NewID(1, lexer.NewTokenWithString(lexer.ID, "a"), expr_type) id_b := inter.NewID(1, lexer.NewTokenWithString
由于语法解析不好用语言说明,有意思的是使用代码反而能描述更清楚,因此我们直接通过代码来理解如何使用生产式来匹配给定的字符串,首先我们对上次完成的lexer做一些修改: package lexer import ]Token), } lexer.reserve() return lexer } func (l *Lexer) ReverseScan() { back_len " ) type SimpleParser struct { lexer lexer.Lexer } func NewSimpleParser(lexer lexer.Lexer) *SimpleParser { return &SimpleParser{ lexer: lexer, } } func (s *SimpleParser) list() error { = nil { return err } if token.Tag == lexer.PLUS || token.Tag == lexer.MINUS {
, []lexer.Tag{lexer.EOF}, 0) initYYDRow(parser, STMT, []lexer.Tag{lexer.NUM, lexer.LEFT_BRACKET}, 1) initYYDRow(parser, EXPR, []lexer.Tag{lexer.EOF, lexer.SEMI, lexer.PLUS, lexer.MUL, lexer.RIGHT_BRACKET , TERM, []lexer.Tag{lexer.EOF, lexer.SEMI, lexer.PLUS, lexer.MUL, lexer.RIGHT_BRACKET}, -1) , []lexer.Tag{lexer.EOF, lexer.MUL, lexer.NUM, lexer.LEFT_BRACKET}, -1) initYYDRow(parser , []lexer.Tag{lexer.EOF, lexer.MUL, lexer.NUM, lexer.MUL, lexer.LEFT_BRACKET}, -1) initYYDRow
switch s.cur_tok.Tag { case lexer.LE: case lexer.LESS_OPERATOR: fallthrough case lexer.GE: fallthrough case lexer.GREATER_OPERATOR: fallthrough case lexer.NE : tok = lexer.NewTokenWithString(s.cur_tok.Tag, s.lexer.Lexeme) default: tok = nil := lexer.NewLexer(source) parser := simple_parser.NewSimpleParser(my_lexer) parser.Parse() } || s.cur_tok.Tag == lexer.NE { tok := lexer.NewTokenWithString(s.cur_tok.Tag, s.lexer.Lexeme
" ) type AugmentedParser struct { parserLexer lexer.Lexer //用于存储虚拟寄存器的名字 registerNames [ } func NewAugmentedParser(parserLexer lexer.Lexer) *AugmentedParser { return &AugmentedParser{ , 0), } } func (a *AugmentedParser) putbackToken(token lexer.Token) { a.reverseToken = append = lexer.EOF { sErr := fmt.Sprintf("get token with err:%s\n", err) panic(sErr) } else if a.match(lexer.LEFT_BRACKET) == true { a.expr() if a.match(lexer.RIGHT_BRACKET
除了这些修改外,lexer的基本逻辑没有什么变化,其代码如下(lexer.go): package lexer import ( "bufio" "strconv" "strings [string]Token), } lexer.reserve() return lexer } func (l *Lexer) ReverseScan() { / var tokens []*lexer.Token tokens = append(tokens, lexer.NewTokenWithString(lexer.SELECT, "select" , lexer.NewTokenWithString(lexer.COMMA, ",")) tokens = append(tokens, lexer.NewTokenWithString(lexer.ID (lexer.WHERE, "where")) tokens = append(tokens, lexer.NewTokenWithString(lexer.ID, "age")) tokens
" ) type SimpleParser struct { lexer lexer.Lexer top *Env saved * (lexer lexer.Lexer) *SimpleParser { return &SimpleParser{ lexer: lexer, top: nil (s.cur_tok.Tag, s.lexer.Lexeme) id := inter.NewID(s.lexer.Line, tok, p) sym := NewSymbol(id, (s.cur_tok.Tag, s.lexer.Lexeme) s.move_forward() x, err = inter.NewArith(s.lexer.Line ", lexer.BASIC, 4) x = inter.NewConstant(s.lexer.Line, tok, t) } else if s.matchTag(lexer.REAL
) p.checkWordTag(lexer.INTO) p.checkWordTag(lexer.ID) tblName := p.sqlLexer.Lexeme p.checkWordTag (lexer.LEFT_BRACKET) flds := p.fieldList() p.checkWordTag(lexer.RIGHT_BRACKET) p.checkWordTag (lexer.VALUES) p.checkWordTag(lexer.LEFT_BRACKET) vals := p.constList() p.checkWordTag(lexer.RIGHT_BRACKET } else if tok.Tag == lexer.VIEW { return p.CreateView() } else if tok.Tag == lexer.INDEX ) idexName := p.sqlLexer.Lexeme p.checkWordTag(lexer.ON) p.checkWordTag(lexer.ID) tableName
= {} lexer. (raw_exp) local new_lexer = setmetatable({}, lexer) new_lexer:init(parse_token(raw_exp)) ) if lexer:match(token_type.num) then lexer:next() elseif lexer:match(token_type.lbrace ) then lexer:next() parser.parse_expression(lexer) lexer:next() elseif lexer elseif lexer:match(token_type.minus) then lexer:next() parser.parse_term(lexer
this.prefixParseFns[this.lexer.BANG_SIGN] = this.parsePrefixExpression this.prefixParseFns[this.lexer.MINUS_SIGN this.lexer.LT] = this.LESSGREATER this.precedencesMap[this.lexer.GT] = this.LESSGREATER this.precedencesMap [this.lexer.PLUS_SIGN] = this.SUM this.precedencesMap[this.lexer.MINUS_SIGN] = this.SUM this.precedencesMap [this.lexer.SLASH] = this.PRODUCT this.precedencesMap[this.lexer.ASTERISK] = this.PRODUCT [this.lexer.ASTERISK] = this.parseInfixExpression this.infixParseFns[this.lexer.EQ] =
然后我们看看其实现: package lexer import ( "bufio" "strconv" "strings" "unicode" ) type Lexer ]Token), } lexer.reserve() return lexer } func (l *Lexer) reserve() { key_words := " ) func main() { source := "if a >= 100.34" my_lexer := lexer.NewLexer(source) for { token, err := my_lexer.Scan() if err ! 代码在这里下载:https://github.com/wycl16514/dragon-compiler-lexer.git
静态规则生成比较特殊,首先,生成规则的写法和上面提到的一致,不同的地方有两点首先是lex::lexertl::lexer的使用要改成lex::lexertl::static_lexer 第二处比较特别, > struct word_count_tokens2 : lex::lexer<Lexer> { word_count_tokens2() : o(0), l(1) , <token_type> lexer_type; word_count_tokens2<lexer_type> word_count_lexer; std::string::iterator Lexer> struct word_count_tokens3 : lex::lexer<Lexer> { word_count_tokens3() { // 命名模式 <lexer_type>::iterator_type iterator_type; word_count_tokens4<lexer_type> word_count; /
" ) type SimpleParser struct { lexer lexer.Lexer top *Env saved *Env } func NewSimpleParser (lexer lexer.Lexer) *SimpleParser { return &SimpleParser{ lexer: lexer, top: nil ) return errors.New(str) } type_str := s.lexer.Lexeme tag, err = s.lexer.Scan() = nil { return err } if tag.Tag == lexer.ID || tag.Tag == lexer.LEFT_BRACE { = lexer.ID { str := fmt.Sprintf("expect identifier , got %s ", s.lexer.Lexeme) return
struct { lexer lexer.Lexer } func NewSimpleParser(lexer lexer.Lexer) *SimpleParser { return &SimpleParser{ lexer: lexer, } } func (s *SimpleParser) list() error { /* 根据生产式 = lexer.NUM || len(s.lexer.Lexeme) > 1 { s := fmt.Sprintf("parsing digit error, got %s", s.lexer.Lexeme tok, err := s.lexer.Scan() if err ! " "simple_parser" ) func main() { source := "9-5+2" my_lexer := lexer.NewLexer(source)
) p.checkWordTag(lexer.FROM) p.checkWordTag(lexer.ID) tblName := p.sqlLexer.Lexeme pred := query.NewPredicate() if p.isMatchTag(lexer.WHERE) { pred = p.Predicate() } return ) p.checkWordTag(lexer.ID) //获得表名 tblName := p.sqlLexer.Lexeme p.checkWordTag(lexer.SET ) _, fldName := p.Field() p.checkWordTag(lexer.ASSIGN_OPERATOR) newVal := p.Expression() pred := query.NewPredicate() if p.isMatchTag(lexer.WHERE) { pred = p.Predicate()
= parser.lexer; Boolean boolObj; try { if (lexer.token() == JSONToken.TRUE) { lexer.nextToken(JSONToken.COMMA); boolObj = Boolean.TRUE; } else if (lexer.token( ; } else if (lexer.token() == JSONToken.LITERAL_INT) { int intValue = lexer.intValue (); if (token == JSONToken.NULL) { lexer.nextToken(); return null; } if ( .class) { String strVal = lexer.stringVal(); lexer.nextToken(); return