All pastes #2120505 Raw Edit

Anonymous

public text v1 · immutable
#2120505 ·published 2012-02-21 19:15 UTC
rendered paste body
%{
// calc is an yacc based toy calculator written in Go.
package main

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

%}

%union{
        val float64
}

%type <val> expr
%token <val> NUMBER

%left '+' '-'
%left '*' '/' '%'
%left UMINUS

%%

list
        : // nothing.
        | list '\n'
        | list expr '\n'        { fmt.Println($2) }
        ;

expr
        : '(' expr ')'          { $$ = $2 }
        | expr '+' expr         { $$ = $1 + $3 }
        | expr '-' expr         { $$ = $1 - $3 }
        | expr '*' expr         { $$ = $1 * $3 }
        | expr '/' expr         { $$ = $1 / $3 }
        | '-' expr %prec UMINUS { $$ = -$2 }
        | NUMBER
        ;
%%

type calcLex struct {
        br *bufio.Reader
}

func (l *calcLex) Lex(lval *yySymType) int {
        for {
                r, _, err := l.br.ReadRune()
                if err != nil {
                        break;
                }

                switch {
                // explicit, so the case below doesn't eat it.
                case r == '\n':
                        return int(r)
                case unicode.IsSpace(r):
                        continue
                case r == '.':
                        fallthrough
                case unicode.IsDigit(r):
                        l.br.UnreadRune()
                        fmt.Fscanf(l.br, "%f", &lval.val)
                        return NUMBER
                default:
                        return int(r)
                }
        }
        return 0
}

func (l *calcLex) Error(s string) {
        fmt.Println(s)
}

func main() {
        yyParse(&calcLex{br: bufio.NewReader(os.Stdin)})
}