При возникновении ошибки - все подпрограммы go находятся в спящем состоянии при реализации лексера в golang - PullRequest
1 голос
/ 18 февраля 2020

Я пытаюсь написать сканер / лексер в go, я подумал, что пойму это, и после попытки реализации я столкнулся с ошибкой, упомянутой в названии. Любой совет?

По сути, я пытаюсь реализовать сканер на основе информации из выступления Роба Пайка на конференции Go в 2011 году. Он говорит об использовании конечного автомата для реализации сканера в Вот как это выглядит:

забавное состояние типа c (s * Scanner) состояние

в основном рекурсивная структура, в моей реализации состояния, в моей функции emit, которую я пытаюсь напечатать подробности о получении токенов.

    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())
}

Здесь мы Возьмите слайды из выступления Роба Пайка на конференции go: https://talks.golang.org/2011/lex.slide#1

Это проект, над которым я сейчас работаю. https://github.com/Apheuz/CPRL

1 Ответ

0 голосов
/ 18 февраля 2020

каналы блокируются.

ваш звонок на

for tok := range s.tokens

будет блокироваться, пока кто-то не пишет в канал или не закрывает его ..

, но никто не будет !

...