cznic / golex

github.com/cznic/golex has moved to modernc.org/golex
https://godoc.org/modernc.org/golex
BSD 3-Clause "New" or "Revised" License
182 stars 18 forks source link

How set input of golex & goyacc as runes Data type? #10

Closed QuestionPython closed 7 years ago

QuestionPython commented 7 years ago

hello,

How set input of golex & goyacc as runes Data type?

lexer.l :

%{
package main
import (
    "bufio"
    "log"
    "strconv"
    "fmt"
)
type yylexer struct{
    src     *bufio.Reader
    buf     []byte
    empty   bool
    current byte
}
func newLexer(src *bufio.Reader) (y *yylexer) {
    fmt.Println(src)
    y = &yylexer{src: src}
    if b, err := src.ReadByte(); err == nil {
        y.current = b
    }
    return
}
func (y *yylexer) getc() byte {
    if y.current != 0 {
        y.buf = append(y.buf, y.current)
    }
    y.current = 0
    if b, err := y.src.ReadByte(); err == nil {
        y.current = b
    }
    return y.current
}
func (y yylexer) Error(e string) {
    log.Fatal(e)
}
func (y *yylexer) Lex(lval *yySymType) int {
    var err error
    c := y.current
    if y.empty {
        c, y.empty = y.getc(), false
    }
%}
%yyc c
%yyn c = y.getc()
D  [0-9]+
E  [eE][-+]?{D}
F  {D}"."{D}?{E}?|{D}{E}?|"."{D}{E}?
%%
    y.buf = y.buf[:0]
[ \t\r]+
{F}
    if lval.value, err = strconv.ParseFloat(string(y.buf), 64); err != nil {
        log.Fatal(err)
    }

    return NUM

%%
    y.empty = true
    return int(c)
}

parser.y file:

%{
package main
import (
    "fmt"
    "math"
)
%}
%union{
    value float64
}
%token  NUM
%left   '-' '+'
%left   '*' '/'
%left   NEG     /* negation--unary minus */
%right  '^'     /* exponentiation */
%type   <value> NUM, exp
%% /* The grammar follows.  */
input:    /* empty */
        | input line
;
line:     '\n'
        | exp '\n'  { fmt.Printf("\t%.10g\n", $1) }
;

exp:      NUM                { $$ = $1          }
        | exp '+' exp        { $$ = $1 + $3     }
        | exp '-' exp        { $$ = $1 - $3     }
        | exp '*' exp        { $$ = $1 * $3     }
        | exp '/' exp        { $$ = $1 / $3     }
        | '-' exp  %prec NEG { $$ = -$2         }
        | exp '^' exp        { $$ = math.Pow($1, $3) }
        | '(' exp ')'        { $$ = $2;         }
;
%%

main.go file:

package main
import (
    "bufio"
    "os"
)func main() {
    yyParse(newLexer(bufio.NewReader(os.Stdin)))
    os.Exit(0)
}

speed for me in important. i want use a good data type, like []byte or []rune! then also can get from file, or inline input.

how fix? may write a good sample ? or help me?

cznic commented 7 years ago

The documentation mentions a Unicode friendly runtime package for lex.

speed for me in important. i want use a good data type, like []byte or []rune! then also can get from file, or inline input.

The New function takes a io.RuneReader as its argument.

QuestionPython commented 7 years ago

available a sample calc with sample vm source with flex,yacc in go?

cznic commented 7 years ago

No, but have a look at the example.l source for inspiration. Or a more real-world example can be seen here.

cznic commented 7 years ago

@questionpython Seems like there's nothing left to do here, closing. Please reopen if you feel otherwise.