구글로 프린터 만들기

14951 단어 자구 해석Go
개략
이번에 저는 goo 언어로 프린터를 만들고 싶었습니다. 필자는 반년 정도의python을 독학했고 프로그래밍에 대한 이해를 더욱 깊이 있게 하기 위해 직접 만들기로 했습니다.
goo언어를 선택한 이유는 정태적인 모드언어를 접하고 싶어서이며 왜 유행하는지 모르겠기 때문이다.
이 보도는 참고Go가 만든 프린터로 진행될 것이다.
이 기사는 제1장을 다 읽었기 때문에 여기에 총결산을 쓴다.
제1장 자구 해석
자구 해석
원본 코드를 영패열로 바꾸는 것을 '자구 해석' 이라고 한다
let x = 5 + 5;

위 그림에서 보듯이token열을 생성합니다
자구 분석기
  • token의 정의
  • token.go
    type Token struct {
        Type string
        Literal string
    }
    const (
        ILLEGAL = "ILLEGAL" // 未知の文字列
        EOF     = "EOF" // 終わりを示す
    
        IDENT = "IDENT" // 識別子
        INT   = "INT" // 数値型
    
        ASSIGN   = "="
        PLUS     = "+"
    
        [...]
    )
    
  • Lexer
  • lexer.go
    type Lexer struct {
        input        string
        position     int // 読み込んでる文字
        readPosition int // 次に読み込む文字
        ch           byte // 検査中の文字
    }
    
    func New(input string) *Lexer {
        // Lexerに引数inputをセットしreturn
        l := &Lexer{input: input}
        l.readChar()
        return l
    }
    
    func (l *Lexer) readChar() {
        // 入力が終わったらchを0に
        if l.readPosition >= len(l.input) {
            l.ch = 0
        // まだ終わっていない場合readPositionをchにセット
        } else {
            l.ch = l.input[l.readPosition]
        }
        // positionを次に進める
        l.position = l.readPosition
        // readpositonを次に進める
        l.readPosition += 1
    }
    
    func (l *Lexer) NextToken() token.Token {
        var tok token.Token
    
        // トークンを生成する
        switch l.ch {
        case '=':
            tok = newToken(token.ASSIGN, l.ch)
        case '+':
            tok = newToken(token.PLUS, l.ch)
        case '-':
            tok = newToken(token.MINUS, l.ch)
        [...]
    
        l.readChar()
        return tok
    }
    
    func newToken(tokenType TokenType, ch byte) Token {
        return Token{Type: tokenType, Literal: string(ch)}
    }
    
    
    이렇게 하면 영패의 생성이 가능하지만, 문자마다 영패가 생성되기 때문에
    let five = 5;
    let ten = 10;
    
    let add = fn(x, y) {
        x + y;
    };
    
    let result = add(five, ten):
    
    상술한 문장을 분석하면 또 문제가 있다
  • 한 글자 한 글자만 해석할 수 있기 때문에let(키워드)으로 오류 발생
  • 1과 마찬가지로five(표지부)로 인한 오류
  • 디지털 분석
  • 먼저 읽기 함수를 실현하여 1, 2의 자모와 도착 비자모를 확정한다
    lexer.go
    // 非英字まで読み込みを進める
    func (l *Lexer) readIdentifier() string {
        position := l.position
        // for文でisLetter関数からfalseが返ってくるまで読み込みを進める
        for isLetter(l.ch) {
            l.readChar()
        }
        // 最初の文字から非英字まで進めたpositionまでを返す
        return l.input[position:l.position]
    }
    // 判断する関数
    func isLetter(ch byte) bool {
        return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z'
    }
    
    이 두 함수를 사용하면NextToken ()의 switch 문장에 지점을 추가할 때 문자열 영패를 성공적으로 생성합니다
    다음은 변수 성명 중의let과 함수fn 등을 분류해야 한다
    token.go
    
    [...]
        FUNCTION = "FUNCTION"
        LET      = "LET"
    
    var keywords = map[string]TokenType{
        "fn":     FUNCTION,
        "let":    LET,
    }
    
    func LookupIdent(ident string) TokenType {
        // readIdentifierで読み込んだ文字列を引数にとり、キーワードに存在する場合は適切なTypeを返す
        if tok, ok := keywords[ident]; ok {
            return tok
        }
        // 識別子の場合
        return IDENT
    }
    
    숫자의 토큰이지만 isLetter와 마찬가지로 분류한다.코드 생략
    1장 마지막에 REPL 설치
    REPL 설치
    이른바 REPL
    R 읽기(읽기)
    EEval(평가)
    Pprint(표시)
    L Loop(중복)
    REPL은 위의 생략입니다.이것은 프린터 언어에서 매우 익숙하여 입력을 받아들이고 평가하며 결과를 반복적으로 출력할 수 있다
    repl.go
    const PROMPO = ">>"
    
    func Start(in io.Reader, out io.Writer) {
        // scannerの生成
        scanner := bufio.NewScanner(in)
    
        for {
            fmt.Printf(PROMPO)
            scanned := scanner.Scan()
            if !scanned {
                return
            }
            // 入力を受け取る
            line := scanner.Text()
            // 解析器に入力された文字列を入れる
            l := lexer.New(line)
    
            // 文字列を評価し出力、これを繰り返す。
            for tok := l.NextToken(); tok.Type != token.EOF; tok = l.NextToken() {
                fmt.Printf("%+v\n", tok)
            }
        }
    }
    
    제1장은 이것으로 끝난다.처음으로 이런 형식으로 배운 것을 총결산하여 보내고 이해를 깊이 있게 하는 것이 의미 있는 방법이라고 생각합니다.
    2장도 계속 업데이트된다.

    좋은 웹페이지 즐겨찾기