首页 > 解决方案 > 遇到错误 - 在 golang 中实现词法分析器时,所有 go 例程都处于休眠状态

问题描述

我正在尝试编写一个扫描仪/词法分析器,我想我会弄明白的,在尝试实现之后我遇到了标题中提到的错误。有什么建议吗?

本质上,我正在尝试根据 Rob Pike 在 2011 年 Go 会议上的演讲中的信息来实现扫描器。他谈到使用有限状态机以类似于以下方式实现扫描器:

type state func(s *Scanner) state

基本上是一个递归结构,在我的状态实现中,在我的发出函数中,我试图打印出有关接收到的令牌的详细信息。

    package scanner

/*
A scanner initializes itself to scan a string/file, then launches a goroutine
that returns the scanner and a channel of items to be tokenized! 
*/
import (
    t "CPRL/token"
    "fmt"
    "io/ioutil"
    "log"
    "strings"
    // "unicode"
)

//Scanner - performs lexical analysis

    type Scanner struct {
        CH rune //character examined

        FILE  string //the name of our current file, used for error reporting
        input string //the string currently being scanned

        start int //start position of our token
        curr  int //current position in input
        line  int //current line we are scanning
        width int //the size of last rune read

        tokens chan t.Token //channel of scanned tokens!

    }


    func (s Scanner) String() string {
        var str []string

        if s.FILE != "" {
            str = append(str, s.FILE+": ")
        }

        return strings.Join(str, "")
    }

//Scan - create a new scanner for current input
func Scan(File string) *Scanner {
    buf, err := ioutil.ReadFile(File)
    if err != nil {
        log.Fatal(err)
    }

    in := string(buf)
    s := &Scanner{
        FILE:   File,
        input:  in,
        line:   1,
        tokens: make(chan t.Token),
    }
    go s.Init()
    return s
}

//Init - initialize a created a scanner

    func (s *Scanner) Init() {
        for state := scanTo; state != nil; {
            state = state(s)
            fmt.Println("State entered")
        }
    }

我正在尝试将所有令牌打印为字符串,代码如下所示,在另一个包中

for tok := range t.Tokens {
  fmt.Println(tok.String())
}

在这里,我们有来自 Rob Pike 在 Go 会议上的演讲的幻灯片: https ://talks.golang.org/2011/lex.slide#1

这是我目前正在做的项目。 https://github.com/Apheuz/CPRL

标签: gocompiler-constructionlexer

解决方案


通道被阻塞。

你的来电

for tok := range s.tokens

将阻塞,直到有人写入频道或关闭它..

但没有人会!


推荐阅读