func(p *Lexer)run()(tokens []token.Token) { deferfunc() { // 捕获errorf方法抛出的异常 tokens = p.tokens if r := recover(); r != nil { if _, ok := r.(token.Token); ok { panic(r) } } }()
for { r := p.src.Read() if r == rune(token.EOF) { p.emit(token.EOF) return } switch { case r == '\n': p.src.IgnoreToken() iflen(p.tokens) > 0 { switch p.tokens[len(p.tokens)-1].Type { case token.RPAREN, token.IDENT, token.NUMBER: p.emit(token.SEMICOLON) } } case isSpace(r): // 空格 p.src.IgnoreToken() case isAlpha(r): // 英文字母 p.src.Unread() for { if r := p.src.Read(); !isAlphaNumeric(r) { p.src.Unread() p.emit(token.IDENT) break } } case ('0' <= r && r <= '9'): // 数字 p.src.Unread()
digits := "0123456789" p.src.AcceptRun(digits) p.emit(token.NUMBER) case r == '+': // 加 p.emit(token.ADD) case r == '-': // 减 p.emit(token.SUB) case r == '*': // 乘 p.emit(token.MUL) case r == '/': if p.src.Peek() != '/' { // 除 p.emit(token.DIV) } else { // 单行注释 for { t := p.src.Read() if t == '\n' { p.src.Unread() p.emitComment() break } if t == rune(token.EOF) { p.emitComment() return } } } case r == '(': p.emit(token.LPAREN) case r == '{': p.emit(token.LBRACE) case r == ')': p.emit(token.RPAREN) case r == '}': p.emit(token.RBRACE) case r == ';': p.emit(token.SEMICOLON) default: p.errorf("unrecognized character: %#U", r) return } } }
for i, tok := range l.Tokens() { fmt.Printf( "%02d: %-12v: %-20q // %s\n", i, tok.Type, tok.Literal, token.PosString("../hello.ugo", code, tok.Pos), ) } fmt.Println("----")
// 遍历注释 for i, tok := range l.Comments() { fmt.Printf( "%02d: %-12v: %-20q // %s\n", i, tok.Type, tok.Literal, token.PosString("../hello.ugo", code, tok.Pos), ) } }
func(p *TokenStream)PeekToken()token.Token { tok := p.ReadToken() p.UnreadToken() return tok }
func(p *TokenStream)AcceptToken(expectTypes ...token.TokenType)(tok token.Token, ok bool) { tok = p.ReadToken() for _, t := range expectTypes { if tok.Type == t { return tok, true } } p.UnreadToken() return tok, false }
func(p *TokenStream)AcceptTokenList(expectTypes ...token.TokenType)(toks []token.Token, ok bool) { for { tok, ok := p.AcceptToken(expectTypes...) if !ok || tok.Type == token.EOF { return toks, len(toks) != 0 } toks = append(toks, tok) } }