Skip to content

Commit

Permalink
feat: move arraiParsers to a separated file
Browse files Browse the repository at this point in the history
  • Loading branch information
ChloePlanet committed May 1, 2020
1 parent 018fa19 commit 6057f1c
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 80 deletions.
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
all: test lint wasm
all: parser test lint wasm

test:
go test $(GOTESTFLAGS) -tags timingsensitive ./...
Expand All @@ -8,3 +8,6 @@ lint:

wasm:
GOOS=js GOARCH=wasm go build -o /tmp/arrai.wasm ./cmd/arrai

parser:
go generate main.go
7 changes: 7 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package main

//go:generate go run tools/parser/generate_parser.go syntax/arrai.wbnf syntax/parser.go
//go:generate goimports -w syntax/parser.go

func main() {
}
70 changes: 70 additions & 0 deletions syntax/arrai.wbnf
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
expr -> C* amp="&"* @ C* arrow=(
nest |
unnest |
ARROW @ |
binding="->" C* "\\" C* IDENT C* %%bind C* @ |
binding="->" C* %%bind @
)* C*
> C* @:binop=("with" | "without") C*
> C* @:binop="||" C*
> C* @:binop="&&" C*
> C* @:compare=/{!?(?:<:|<>?=?|>=?|=)} C*
> C* @ if=("if" t=expr ("else" f=expr)?)* C*
> C* @:binop=/{\+\+|[+|]|-%?} C*
> C* @:binop=/{&~|&|~~?|[-<][-&][->]} C*
> C* @:binop=/{//|[*/%]|\\} C*
> C* @:rbinop="^" C*
> C* unop=/{:>|=>|>>|[-+!*^]}* @ C*
> C* @:binop=">>>" C*
> C* @ count="count"? C* touch? C*
> C* (get | @) tail=(
get
| call=("("
arg=(
expr (":" end=expr? (":" step=expr)?)?
| ":" end=expr (":" step=expr)?
):",",
")")
)* C*
> C* "{" C* rel=(names tuple=("(" v=@:",", ")"):",",?) "}" C*
| C* "{" C* set=(elt=@:",",?) "}" C*
| C* "{" C* dict=((key=@ ":" value=@):",",?) "}" C*
| C* cond=("cond" "(" (key=@ ":" value=@):",",? ("*" ":" f=expr)? ")") C*
| C* cond=(("(" control_var=expr ")" | IDENT)? C* "cond" "(" (key=@ ":" value=@):",",? ("*" ":" f=expr)? ")") C*
| C* "[" C* array=(item=@:",",?) "]" C*
| C* "{:" C* embed=(grammar=@ ":" subgrammar=%%ast) ":}" C*
| C* op="\\\\" @ C*
| C* fn="\\" IDENT @ C*
| C* "//" pkg=( "{" dot="."? PKGPATH "}" | std=IDENT?)
| C* "(" tuple=(pairs=(name? ":" v=@):",",?) ")" C*
| C* "(" @ ")" C*
| C* let=("let" C* IDENT C* "=" C* @ %%bind C* ";" C* @) C*
| C* xstr C*
| C* IDENT C*
| C* STR C*
| C* NUM C*;
nest -> C* "nest" names IDENT C*;
unnest -> C* "unnest" IDENT C*;
touch -> C* ("->*" ("&"? IDENT | STR))+ "(" expr:"," ","? ")" C*;
get -> C* dot="." ("&"? IDENT | STR | "*") C*;
names -> C* "|" C* IDENT:"," C* "|" C*;
name -> C* IDENT C* | C* STR C*;
xstr -> C* quote=/{\$"\s*} part=( sexpr | fragment=/{(?: \\. | \$[^{"] | [^\\"$] )+} )* '"' C*
| C* quote=/{\$'\s*} part=( sexpr | fragment=/{(?: \\. | \$[^{'] | [^\\'$] )+} )* "'" C*
| C* quote=/{\$‵\s*} part=( sexpr | fragment=/{(?: ‵‵ | \$[^{‵] | [^‵ $] )+} )* "‵" C*;
sexpr -> "${"
C* expr C*
control=/{ (?: : [-+#*\.\_0-9a-z]* (?: : (?: \\. | [^\\:}] )* ){0,2} )? }
close=/{\}\s*};

ARROW -> /{:>|=>|>>|orderby|order|where|sum|max|mean|median|min};
IDENT -> /{ \. | [$@A-Za-z_][0-9$@A-Za-z_]* };
PKGPATH -> /{ (?: \\ | [^\\}] )* };
STR -> /{ " (?: \\. | [^\\"] )* "
| ' (?: \\. | [^\\'] )* '
| ‵ (?: ‵‵ | [^‵ ] )* ‵
};
NUM -> /{ (?: \d+(?:\.\d*)? | \.\d+ ) (?: [Ee][-+]?\d+ )? };
C -> /{ # .* $ };

.wrapRE -> /{\s*()\s*};
79 changes: 0 additions & 79 deletions syntax/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package syntax
import (
"fmt"
"log"
"strings"

"github.com/arr-ai/wbnf/ast"
"github.com/arr-ai/wbnf/wbnf"
Expand All @@ -22,84 +21,6 @@ import (

// var noParse = &noParseType{}

func unfakeBackquote(s string) string {
return strings.ReplaceAll(s, "‵", "`")
}

var arraiParsers = wbnf.MustCompile(unfakeBackquote(`
expr -> C* amp="&"* @ C* arrow=(
nest |
unnest |
ARROW @ |
binding="->" C* "\\" C* IDENT C* %%bind C* @ |
binding="->" C* %%bind @
)* C*
> C* @:binop=("with" | "without") C*
> C* @:binop="||" C*
> C* @:binop="&&" C*
> C* @:compare=/{!?(?:<:|<>?=?|>=?|=)} C*
> C* @ if=("if" t=expr ("else" f=expr)?)* C*
> C* @:binop=/{\+\+|[+|]|-%?} C*
> C* @:binop=/{&~|&|~~?|[-<][-&][->]} C*
> C* @:binop=/{//|[*/%]|\\} C*
> C* @:rbinop="^" C*
> C* unop=/{:>|=>|>>|[-+!*^]}* @ C*
> C* @:binop=">>>" C*
> C* @ count="count"? C* touch? C*
> C* (get | @) tail=(
get
| call=("("
arg=(
expr (":" end=expr? (":" step=expr)?)?
| ":" end=expr (":" step=expr)?
):",",
")")
)* C*
> C* "{" C* rel=(names tuple=("(" v=@:",", ")"):",",?) "}" C*
| C* "{" C* set=(elt=@:",",?) "}" C*
| C* "{" C* dict=((key=@ ":" value=@):",",?) "}" C*
| C* cond=("cond" "(" (key=@ ":" value=@):",",? ("*" ":" f=expr)? ")") C*
| C* cond=(("(" control_var=expr ")" | IDENT)? C* "cond" "(" (key=@ ":" value=@):",",? ("*" ":" f=expr)? ")") C*
| C* "[" C* array=(item=@:",",?) "]" C*
| C* "{:" C* embed=(grammar=@ ":" subgrammar=%%ast) ":}" C*
| C* op="\\\\" @ C*
| C* fn="\\" IDENT @ C*
| C* "//" pkg=( "{" dot="."? PKGPATH "}" | std=IDENT?
)
| C* "(" tuple=(pairs=(name? ":" v=@):",",?) ")" C*
| C* "(" @ ")" C*
| C* let=("let" C* IDENT C* "=" C* @ %%bind C* ";" C* @) C*
| C* xstr C*
| C* IDENT C*
| C* STR C*
| C* NUM C*;
nest -> C* "nest" names IDENT C*;
unnest -> C* "unnest" IDENT C*;
touch -> C* ("->*" ("&"? IDENT | STR))+ "(" expr:"," ","? ")" C*;
get -> C* dot="." ("&"? IDENT | STR | "*") C*;
names -> C* "|" C* IDENT:"," C* "|" C*;
name -> C* IDENT C* | C* STR C*;
xstr -> C* quote=/{\$"\s*} part=( sexpr | fragment=/{(?: \\. | \$[^{"] | [^\\"$] )+} )* '"' C*
| C* quote=/{\$'\s*} part=( sexpr | fragment=/{(?: \\. | \$[^{'] | [^\\'$] )+} )* "'" C*
| C* quote=/{\$‵\s*} part=( sexpr | fragment=/{(?: ‵‵ | \$[^{‵] | [^‵ $] )+} )* "‵" C*;
sexpr -> "${"
C* expr C*
control=/{ (?: : [-+#*\.\_0-9a-z]* (?: : (?: \\. | [^\\:}] )* ){0,2} )? }
close=/{\}\s*};
ARROW -> /{:>|=>|>>|orderby|order|where|sum|max|mean|median|min};
IDENT -> /{ \. | [$@A-Za-z_][0-9$@A-Za-z_]* };
PKGPATH -> /{ (?: \\ | [^\\}] )* };
STR -> /{ " (?: \\. | [^\\"] )* "
| ' (?: \\. | [^\\'] )* '
| ‵ (?: ‵‵ | [^‵ ] )* ‵
};
NUM -> /{ (?: \d+(?:\.\d*)? | \.\d+ ) (?: [Ee][-+]?\d+ )? };
C -> /{ # .* $ };
.wrapRE -> /{\s*()\s*};
`), nil)

type ParseContext struct {
SourceDir string
}
Expand Down
84 changes: 84 additions & 0 deletions syntax/parser.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package syntax

import (
"strings"

"github.com/arr-ai/wbnf/wbnf"
)

func unfakeBackquote(s string) string {
return strings.ReplaceAll(s, "`", "`")
}

var arraiParsers = wbnf.MustCompile(unfakeBackquote(`
expr -> C* amp="&"* @ C* arrow=(
nest |
unnest |
ARROW @ |
binding="->" C* "\\" C* IDENT C* %%bind C* @ |
binding="->" C* %%bind @
)* C*
> C* @:binop=("with" | "without") C*
> C* @:binop="||" C*
> C* @:binop="&&" C*
> C* @:compare=/{!?(?:<:|<>?=?|>=?|=)} C*
> C* @ if=("if" t=expr ("else" f=expr)?)* C*
> C* @:binop=/{\+\+|[+|]|-%?} C*
> C* @:binop=/{&~|&|~~?|[-<][-&][->]} C*
> C* @:binop=/{//|[*/%]|\\} C*
> C* @:rbinop="^" C*
> C* unop=/{:>|=>|>>|[-+!*^]}* @ C*
> C* @:binop=">>>" C*
> C* @ count="count"? C* touch? C*
> C* (get | @) tail=(
get
| call=("("
arg=(
expr (":" end=expr? (":" step=expr)?)?
| ":" end=expr (":" step=expr)?
):",",
")")
)* C*
> C* "{" C* rel=(names tuple=("(" v=@:",", ")"):",",?) "}" C*
| C* "{" C* set=(elt=@:",",?) "}" C*
| C* "{" C* dict=((key=@ ":" value=@):",",?) "}" C*
| C* cond=("cond" "(" (key=@ ":" value=@):",",? ("*" ":" f=expr)? ")") C*
| C* cond=(("(" control_var=expr ")" | IDENT)? C* "cond" "(" (key=@ ":" value=@):",",? ("*" ":" f=expr)? ")") C*
| C* "[" C* array=(item=@:",",?) "]" C*
| C* "{:" C* embed=(grammar=@ ":" subgrammar=%%ast) ":}" C*
| C* op="\\\\" @ C*
| C* fn="\\" IDENT @ C*
| C* "//" pkg=( "{" dot="."? PKGPATH "}" | std=IDENT?)
| C* "(" tuple=(pairs=(name? ":" v=@):",",?) ")" C*
| C* "(" @ ")" C*
| C* let=("let" C* IDENT C* "=" C* @ %%bind C* ";" C* @) C*
| C* xstr C*
| C* IDENT C*
| C* STR C*
| C* NUM C*;
nest -> C* "nest" names IDENT C*;
unnest -> C* "unnest" IDENT C*;
touch -> C* ("->*" ("&"? IDENT | STR))+ "(" expr:"," ","? ")" C*;
get -> C* dot="." ("&"? IDENT | STR | "*") C*;
names -> C* "|" C* IDENT:"," C* "|" C*;
name -> C* IDENT C* | C* STR C*;
xstr -> C* quote=/{\$"\s*} part=( sexpr | fragment=/{(?: \\. | \$[^{"] | [^\\"$] )+} )* '"' C*
| C* quote=/{\$'\s*} part=( sexpr | fragment=/{(?: \\. | \$[^{'] | [^\\'$] )+} )* "'" C*
| C* quote=/{\$‵\s*} part=( sexpr | fragment=/{(?: ‵‵ | \$[^{‵] | [^‵ $] )+} )* "‵" C*;
sexpr -> "${"
C* expr C*
control=/{ (?: : [-+#*\.\_0-9a-z]* (?: : (?: \\. | [^\\:}] )* ){0,2} )? }
close=/{\}\s*};
ARROW -> /{:>|=>|>>|orderby|order|where|sum|max|mean|median|min};
IDENT -> /{ \. | [$@A-Za-z_][0-9$@A-Za-z_]* };
PKGPATH -> /{ (?: \\ | [^\\}] )* };
STR -> /{ " (?: \\. | [^\\"] )* "
| ' (?: \\. | [^\\'] )* '
| ‵ (?: ‵‵ | [^‵ ] )* ‵
};
NUM -> /{ (?: \d+(?:\.\d*)? | \.\d+ ) (?: [Ee][-+]?\d+ )? };
C -> /{ # .* $ };
.wrapRE -> /{\s*()\s*};
`), nil)
26 changes: 26 additions & 0 deletions tools/parser/generate_parser.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package main

import (
"fmt"
"io/ioutil"
"os"
)

// Reads ../syntax/arrai.wbnf file
// and encodes them as strings literals in ../syntax/parser.go
func main() {
data, err := ioutil.ReadFile(os.Args[1])
if err != nil {
panic(err)
}

content := append(
[]byte("package syntax\n\nfunc unfakeBackquote(s string) string {\n return strings.ReplaceAll(s, \"`\", \"`\")\n}\n\nvar arraiParsers = wbnf.MustCompile(unfakeBackquote(`\n"), //nolint:lll
data...)
content = append(content, []byte("\n`), nil)")...)
err = ioutil.WriteFile(os.Args[2], content, 0644)
if err != nil {
panic(err)
}
fmt.Println("arrai parser generated")
}

0 comments on commit 6057f1c

Please sign in to comment.