【Interpreter】构建简单的解释器(第1部分—Go语言实现)

【Interpreter】构建简单的解释器(第1部分—Go语言实现)

一、描述

  1. 能够计算两个个位整数的和,如 3 + 5。

二、代码

// 使用 Go 简单实现

package main

import (
	"bufio"
	"fmt"
	"os"
	"strings"
	"unicode"
)

type TOKENTYPE int

const (
	TYPE_NONE TOKENTYPE = iota
	TYPE_INTEGER
	TYPE_PLUS
	TYPE_EOF
)

type Token struct {
	token_char interface{}
	token_type TOKENTYPE
}

type Interpreter struct {
	text          []rune
	pos           int
	current_token Token
}

func RuneToInt(c rune) (int, bool) {
	if unicode.IsDigit(c) {
		return int(c - '0'), true
	}
	return 0, false
}

func (interpreter *Interpreter) Eat(token_type TOKENTYPE) {
	if interpreter.current_token.token_type == token_type {
		interpreter.current_token = interpreter.GetNextToken()
		return
	}

	panic("type error.")
}

func (interpreter *Interpreter) GetNextToken() Token {
	text := interpreter.text

	if interpreter.pos <= len(text)-1 {

		current_char := interpreter.text[interpreter.pos]

		if v, ok := RuneToInt(current_char); ok {
			token := Token{v, TYPE_INTEGER}
			interpreter.pos++
			return token
		}

		if '+' == current_char {
			token := Token{current_char, TYPE_PLUS}
			interpreter.pos++
			return token
		}
	}

	return Token{TYPE_EOF, 0}
}

func (interpreter *Interpreter) Expr() {

	defer func() {
		if r := recover(); r != nil {
			fmt.Println("[ERROR] ", r)
		}
	}()

	interpreter.current_token = interpreter.GetNextToken()

	left := interpreter.current_token
	interpreter.Eat(TYPE_INTEGER)

	// operator := interpreter.current_token
	interpreter.Eat(TYPE_PLUS)

	right := interpreter.current_token

	result := left.token_char.(int) + right.token_char.(int)

	fmt.Println("> ", result)
}

func main() {
	fmt.Println("------------------ <PART-1> ------------------")
	reader := bufio.NewReader(os.Stdin)

	for {
		fmt.Print("[CALC]-> ")

		text, _ := reader.ReadString('\n')
		my_text := strings.TrimSpace(strings.TrimSuffix(strings.ToLower(text), "\n"))

		if len(my_text) == 0 {
			continue
		}

		if my_text == "exit" {
			fmt.Println("-------------------程序已退出-------------------")
			fmt.Println("------------------- <END> --------------------")
			os.Exit(0)
		}

		// 处理字符串
		interpreter := Interpreter{[]rune(my_text), 0, Token{}}
		interpreter.Expr()
	}
}

三、运行结果

------------------ <PART-1> ------------------
[CALC]-> 1+2
>  3
[CALC]-> 1+9
>  10
[CALC]-> 3+5
>  8
[CALC]-> 11+1
[ERROR]  type error.
[CALC]-> 1 +2 
[ERROR]  type error.
[CALC]-> exit
-------------------程序已退出-------------------
------------------- <END> --------------------

——2019-01-15——

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值