Skip to content

Commit

Permalink
Functional is constructed within parser, not scanner
Browse files Browse the repository at this point in the history
  • Loading branch information
osteele committed Jun 26, 2017
1 parent 6af4fca commit c02fbd5
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 40 deletions.
4 changes: 2 additions & 2 deletions chunk_ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
23 changes: 13 additions & 10 deletions chunk_parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"bytes"
"fmt"
"testing"

"github.com/stretchr/testify/require"
Expand All @@ -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)
})
}
}

Expand Down
13 changes: 8 additions & 5 deletions expression_parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 14 additions & 15 deletions scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)--
{
Expand All @@ -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
Expand All @@ -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)--

Expand All @@ -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
Expand All @@ -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
}
}

Expand All @@ -348,7 +347,7 @@ _again:
//line NONE:1
lex.ts = 0

//line scanner.go:352
//line scanner.go:351
}
}

Expand All @@ -370,7 +369,7 @@ _again:
_out: {}
}

//line scanner.rl:71
//line scanner.rl:70


return tok
Expand Down
9 changes: 4 additions & 5 deletions scanner.rl
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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; }
Expand Down
19 changes: 16 additions & 3 deletions y.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 */
Expand Down

0 comments on commit c02fbd5

Please sign in to comment.