mirror of
https://github.com/danog/liquid.git
synced 2025-01-22 23:11:25 +01:00
Functional is constructed within parser, not scanner
This commit is contained in:
parent
6af4fca71b
commit
c02fbd57ac
@ -33,8 +33,8 @@ type ASTControlTag struct {
|
||||
branches []*ASTControlTag
|
||||
}
|
||||
|
||||
func (n ASTSeq) String() string {
|
||||
b, err := yaml.Marshal(n)
|
||||
func MustYAML(val interface{}) string {
|
||||
b, err := yaml.Marshal(val)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
@ -13,16 +14,18 @@ func TestChunkParser(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range chunkTests {
|
||||
tokens := ScanChunks(test.in, "")
|
||||
// fmt.Println(tokens)
|
||||
ast, err := Parse(tokens)
|
||||
require.NoError(t, err, test.in)
|
||||
// fmt.Println("%#v", ast)
|
||||
buf := new(bytes.Buffer)
|
||||
err = ast.Render(buf, ctx)
|
||||
require.NoError(t, err, test.in)
|
||||
require.Equal(t, test.expected, buf.String(), test.in)
|
||||
for i, test := range chunkTests {
|
||||
t.Run(fmt.Sprint(i), func(t *testing.T) {
|
||||
tokens := ScanChunks(test.in, "")
|
||||
// fmt.Println(tokens)
|
||||
ast, err := Parse(tokens)
|
||||
require.NoErrorf(t, err, test.in)
|
||||
// fmt.Println(MustYAML(ast))
|
||||
buf := new(bytes.Buffer)
|
||||
err = ast.Render(buf, ctx)
|
||||
require.NoErrorf(t, err, test.in)
|
||||
require.Equalf(t, test.expected, buf.String(), test.in)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,12 +6,15 @@ import (
|
||||
%}
|
||||
%union {
|
||||
name string
|
||||
val func(Context) interface{}
|
||||
val interface{}
|
||||
f func(Context) interface{}
|
||||
}
|
||||
%type <val> expr
|
||||
%token <val> LITERAL IDENTIFIER
|
||||
%token <name> RELATION
|
||||
%type <f> expr
|
||||
%token <val> LITERAL
|
||||
%token <name> IDENTIFIER RELATION
|
||||
%%
|
||||
top: expr { yylex.(*lexer).val = $1 };
|
||||
|
||||
expr: LITERAL | IDENTIFIER;
|
||||
expr:
|
||||
LITERAL { $$ = func(_ Context) interface{} { return $1 } }
|
||||
| IDENTIFIER { $$ = func(ctx Context) interface{} { return ctx.Variables[$1] } }
|
||||
|
29
scanner.go
29
scanner.go
@ -263,18 +263,18 @@ _eof_trans:
|
||||
//line scanner.rl:36
|
||||
lex.act = 2;
|
||||
case 4:
|
||||
//line scanner.rl:56
|
||||
//line scanner.rl:55
|
||||
lex.act = 4;
|
||||
case 5:
|
||||
//line scanner.rl:41
|
||||
lex.act = 5;
|
||||
case 6:
|
||||
//line scanner.rl:56
|
||||
//line scanner.rl:55
|
||||
lex.te = ( lex.p)+1
|
||||
{ tok = RELATION; out.name = string(lex.data[lex.ts:lex.te]); ( lex.p)++; goto _out
|
||||
}
|
||||
case 7:
|
||||
//line scanner.rl:47
|
||||
//line scanner.rl:46
|
||||
lex.te = ( lex.p)
|
||||
( lex.p)--
|
||||
{
|
||||
@ -283,12 +283,12 @@ _eof_trans:
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
out.val = func(_ Context) interface{} { return n }
|
||||
out.val = n
|
||||
( lex.p)++; goto _out
|
||||
|
||||
}
|
||||
case 8:
|
||||
//line scanner.rl:56
|
||||
//line scanner.rl:55
|
||||
lex.te = ( lex.p)
|
||||
( lex.p)--
|
||||
{ tok = RELATION; out.name = string(lex.data[lex.ts:lex.te]); ( lex.p)++; goto _out
|
||||
@ -299,13 +299,12 @@ _eof_trans:
|
||||
( lex.p)--
|
||||
{
|
||||
tok = IDENTIFIER
|
||||
name := string(lex.data[lex.ts:lex.te])
|
||||
out.val = func(ctx Context) interface{} { return ctx.Variables[name] }
|
||||
out.name = string(lex.data[lex.ts:lex.te])
|
||||
( lex.p)++; goto _out
|
||||
|
||||
}
|
||||
case 10:
|
||||
//line scanner.rl:67
|
||||
//line scanner.rl:66
|
||||
lex.te = ( lex.p)
|
||||
( lex.p)--
|
||||
|
||||
@ -316,8 +315,9 @@ _eof_trans:
|
||||
{( lex.p) = ( lex.te) - 1
|
||||
|
||||
tok = LITERAL
|
||||
val := string(lex.data[lex.ts:lex.te]) == "true"
|
||||
out.val = func(_ Context) interface{} { return val }
|
||||
out.val = string(lex.data[lex.ts:lex.te]) == "true"
|
||||
( lex.p)++; goto _out
|
||||
|
||||
}
|
||||
case 4:
|
||||
{( lex.p) = ( lex.te) - 1
|
||||
@ -327,14 +327,13 @@ _eof_trans:
|
||||
{( lex.p) = ( lex.te) - 1
|
||||
|
||||
tok = IDENTIFIER
|
||||
name := string(lex.data[lex.ts:lex.te])
|
||||
out.val = func(ctx Context) interface{} { return ctx.Variables[name] }
|
||||
out.name = string(lex.data[lex.ts:lex.te])
|
||||
( lex.p)++; goto _out
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//line scanner.go:338
|
||||
//line scanner.go:337
|
||||
}
|
||||
}
|
||||
|
||||
@ -348,7 +347,7 @@ _again:
|
||||
//line NONE:1
|
||||
lex.ts = 0
|
||||
|
||||
//line scanner.go:352
|
||||
//line scanner.go:351
|
||||
}
|
||||
}
|
||||
|
||||
@ -370,7 +369,7 @@ _again:
|
||||
_out: {}
|
||||
}
|
||||
|
||||
//line scanner.rl:71
|
||||
//line scanner.rl:70
|
||||
|
||||
|
||||
return tok
|
||||
|
@ -35,13 +35,12 @@ func (lex *lexer) Lex(out *yySymType) int {
|
||||
%%{
|
||||
action Bool {
|
||||
tok = LITERAL
|
||||
val := string(lex.data[lex.ts:lex.te]) == "true"
|
||||
out.val = func(_ Context) interface{} { return val }
|
||||
out.val = string(lex.data[lex.ts:lex.te]) == "true"
|
||||
fbreak;
|
||||
}
|
||||
action Ident {
|
||||
tok = IDENTIFIER
|
||||
name := string(lex.data[lex.ts:lex.te])
|
||||
out.val = func(ctx Context) interface{} { return ctx.Variables[name] }
|
||||
out.name = string(lex.data[lex.ts:lex.te])
|
||||
fbreak;
|
||||
}
|
||||
action Number {
|
||||
@ -50,7 +49,7 @@ func (lex *lexer) Lex(out *yySymType) int {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
out.val = func(_ Context) interface{} { return n }
|
||||
out.val = n
|
||||
fbreak;
|
||||
}
|
||||
action Relation { tok = RELATION; out.name = string(lex.data[lex.ts:lex.te]); fbreak; }
|
||||
|
19
y.go
19
y.go
@ -12,7 +12,8 @@ import (
|
||||
type yySymType struct {
|
||||
yys int
|
||||
name string
|
||||
val func(Context) interface{}
|
||||
val interface{}
|
||||
f func(Context) interface{}
|
||||
}
|
||||
|
||||
const LITERAL = 57346
|
||||
@ -423,9 +424,21 @@ yydefault:
|
||||
|
||||
case 1:
|
||||
yyDollar = yyS[yypt-1 : yypt+1]
|
||||
//line expression_parser.y:15
|
||||
//line expression_parser.y:16
|
||||
{
|
||||
yylex.(*lexer).val = yyDollar[1].val
|
||||
yylex.(*lexer).val = yyDollar[1].f
|
||||
}
|
||||
case 2:
|
||||
yyDollar = yyS[yypt-1 : yypt+1]
|
||||
//line expression_parser.y:19
|
||||
{
|
||||
yyVAL.f = func(_ Context) interface{} { return yyDollar[1].val }
|
||||
}
|
||||
case 3:
|
||||
yyDollar = yyS[yypt-1 : yypt+1]
|
||||
//line expression_parser.y:20
|
||||
{
|
||||
yyVAL.f = func(ctx Context) interface{} { return ctx.Variables[yyDollar[1].name] }
|
||||
}
|
||||
}
|
||||
goto yystack /* stack new state and value */
|
||||
|
Loading…
x
Reference in New Issue
Block a user