mirror of
https://github.com/danog/liquid.git
synced 2024-11-30 10:39:01 +01:00
72 lines
1.4 KiB
Ragel
72 lines
1.4 KiB
Ragel
// Adapted from https://github.com/mhamrah/thermostat
|
|
package main
|
|
|
|
import "fmt"
|
|
import "strconv"
|
|
|
|
%%{
|
|
machine expression;
|
|
write data;
|
|
access lex.;
|
|
variable p lex.p;
|
|
variable pe lex.pe;
|
|
}%%
|
|
|
|
type lexer struct {
|
|
data []byte
|
|
p, pe, cs int
|
|
ts, te, act int
|
|
val func(Context) interface{}
|
|
}
|
|
|
|
func newLexer(data []byte) *lexer {
|
|
lex := &lexer{
|
|
data: data,
|
|
pe: len(data),
|
|
}
|
|
%% write init;
|
|
return lex
|
|
}
|
|
|
|
func (lex *lexer) Lex(out *yySymType) int {
|
|
eof := lex.pe
|
|
tok := 0
|
|
|
|
%%{
|
|
action Ident {
|
|
tok = IDENTIFIER
|
|
name := string(lex.data[lex.ts:lex.te])
|
|
out.val = func(ctx Context) interface{} { return ctx.Variables[name] }
|
|
fbreak;
|
|
}
|
|
action Number {
|
|
tok = NUMBER
|
|
n, err := strconv.ParseFloat(string(lex.data[lex.ts:lex.te]), 64)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
out.val = func(_ Context) interface{} { return n }
|
|
fbreak;
|
|
}
|
|
action Relation { tok = RELATION; out.name = string(lex.data[lex.ts:lex.te]); fbreak; }
|
|
|
|
ident = (alpha | '_') . (alnum | '_')* ;
|
|
number = '-'? (digit+ ('.' digit*)?) ;
|
|
|
|
main := |*
|
|
ident => Ident; #{ tok = IDENTIFIER; out.name = string(lex.data[lex.ts:lex.te]); fbreak; };
|
|
number => Number;
|
|
("==" | "!=" | ">" | ">" | ">=" | "<=") => Relation;
|
|
("and" | "or" | "contains") => Relation;
|
|
space+;
|
|
*|;
|
|
|
|
write exec;
|
|
}%%
|
|
|
|
return tok
|
|
}
|
|
|
|
func (lex *lexer) Error(e string) {
|
|
fmt.Println("error:", e)
|
|
} |