80 lines
1.7 KiB
Plaintext
80 lines
1.7 KiB
Plaintext
|
%{
|
||
|
// Copyright (c) 2015 The golex Authors. All rights reserved.
|
||
|
// Use of this source code is governed by a BSD-style
|
||
|
// license that can be found in the LICENSE file.
|
||
|
|
||
|
// This is an example program using golex run time library.
|
||
|
package main
|
||
|
|
||
|
import (
|
||
|
"bufio"
|
||
|
"go/token"
|
||
|
"io"
|
||
|
"unicode"
|
||
|
|
||
|
"github.com/cznic/golex/lex"
|
||
|
)
|
||
|
|
||
|
// Allocate Character classes anywhere in [0x80, 0xFF].
|
||
|
const (
|
||
|
classUnicodeLeter = iota + 0x80
|
||
|
classUnicodeDigit
|
||
|
classOther
|
||
|
)
|
||
|
|
||
|
type lexer struct {
|
||
|
*lex.Lexer
|
||
|
}
|
||
|
|
||
|
func rune2Class(r rune) int {
|
||
|
if r >= 0 && r < 0x80 { // Keep ASCII as it is.
|
||
|
return int(r)
|
||
|
}
|
||
|
if unicode.IsLetter(r) {
|
||
|
return classUnicodeLeter
|
||
|
}
|
||
|
if unicode.IsDigit(r) {
|
||
|
return classUnicodeDigit
|
||
|
}
|
||
|
return classOther
|
||
|
}
|
||
|
|
||
|
func newLexer(src io.Reader, dst io.Writer, fName string) *lexer {
|
||
|
file := token.NewFileSet().AddFile(fName, -1, 1<<31-1)
|
||
|
lx, err := lex.New(file, bufio.NewReader(src), lex.RuneClass(rune2Class))
|
||
|
if (err != nil) { panic(err) }
|
||
|
return &lexer{lx}
|
||
|
}
|
||
|
|
||
|
func (l *lexer) Lex(lval *yySymType) int {
|
||
|
c := l.Enter()
|
||
|
|
||
|
%}
|
||
|
|
||
|
%yyc c
|
||
|
%yyn c = l.Next()
|
||
|
%yym l.Mark()
|
||
|
|
||
|
digit [0-9]|{unicodeDigit}
|
||
|
identifier {letter}({letter}|{digit})*
|
||
|
int {digit}+
|
||
|
letter [_a-zA-Z]|{unicodeLetter}
|
||
|
unicodeDigit \x81
|
||
|
unicodeLetter \x80
|
||
|
op [-+*/]
|
||
|
|
||
|
%%
|
||
|
c = l.Rule0()
|
||
|
|
||
|
[ \t\r\n]+
|
||
|
[/][/][^\n]+ lval.token = string(l.TokenBytes(nil)); return COMMENT
|
||
|
func lval.token = string(l.TokenBytes(nil)); return FUNC
|
||
|
{identifier} lval.token = string(l.TokenBytes(nil)); return IDENT
|
||
|
{int} lval.token = string(l.TokenBytes(nil)); return INT
|
||
|
{op} lval.token = string(l.TokenBytes(nil)); return OP
|
||
|
|
||
|
%%
|
||
|
if c, ok := l.Abort(); ok { return int(c) }
|
||
|
goto yyAction
|
||
|
}
|