From 80c277773a1e73267832641574654361b85e6028 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Mon, 10 Jul 2023 15:54:13 +0200 Subject: first commit --- parser/parse_test.go | 228 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 228 insertions(+) create mode 100644 parser/parse_test.go (limited to 'parser/parse_test.go') diff --git a/parser/parse_test.go b/parser/parse_test.go new file mode 100644 index 0000000..dc363cb --- /dev/null +++ b/parser/parse_test.go @@ -0,0 +1,228 @@ +package parser + +import ( + "os" + "testing" + + "github.com/gnolang/parscan/scanner" +) + +var GoScanner = &scanner.Scanner{ + CharProp: [scanner.ASCIILen]uint{ + '\t': scanner.CharSep, + '\n': scanner.CharLineSep, + ' ': scanner.CharSep, + '!': scanner.CharOp, + '"': scanner.CharStr, + '%': scanner.CharOp, + '&': scanner.CharOp, + '\'': scanner.CharStr, + '(': scanner.CharBlock, + '*': scanner.CharOp, + '+': scanner.CharOp, + ',': scanner.CharGroupSep, + '-': scanner.CharOp, + '.': scanner.CharOp, + '/': scanner.CharOp, + ':': scanner.CharOp, + ';': scanner.CharGroupSep, + '<': scanner.CharOp, + '=': scanner.CharOp, + '>': scanner.CharOp, + '[': scanner.CharBlock, + '^': scanner.CharOp, + '{': scanner.CharBlock, + '|': scanner.CharOp, + '~': scanner.CharOp, + }, + End: map[string]string{ + "(": ")", + "{": "}", + "[": "]", + "/*": "*/", + `"`: `"`, + "'": "'", + "`": "`", + "//": "\n", + }, +} + +const ( + Undefined = Kind(iota) + FuncDecl + CallExpr + IfStmt + StmtBloc + ReturnStmt + ParBloc + MulOp + AddOp + SubOp + DotOp + AssignOp + DefOp + InfOp +) + +var GoParser = &Parser{ + Scanner: GoScanner, + Spec: map[string]NodeSpec{ + ".": {DotOp, Call, 3}, + "*": {MulOp, 0, 4}, + "+": {AddOp, 0, 5}, + "-": {SubOp, 0, 5}, + "<": {InfOp, 0, 6}, + ":=": {DefOp, 0, 7}, + "=": {AssignOp, 0, 7}, + "#Call": {CallExpr, 0, 0}, + "if": {IfStmt, Stmt | ExprSep, 0}, + "func": {FuncDecl, Decl | Call, 0}, + "return": {ReturnStmt, Stmt, 0}, + "{..}": {StmtBloc, ExprSep, 0}, + "{": {StmtBloc, ExprSep, 0}, + "(": {ParBloc, Call, 0}, + "(..)": {ParBloc, Call, 0}, + }, +} + +func TestParse(t *testing.T) { + for _, test := range goTests { + t.Run("", func(t *testing.T) { + var err error + errStr := "" + n := &Node{} + if n.Child, err = GoParser.Parse(test.src); err != nil { + errStr = err.Error() + } + if errStr != test.err { + t.Errorf("got error %#v, want error %#v", errStr, test.err) + } + if dot := n.Sdot(""); dot != test.dot { + t.Errorf("got %#v, want %#v", dot, test.dot) + } + t.Log(test.src) + t.Log(n.Sdot("")) + if dotCmd := os.Getenv("DOT"); dotCmd != "" { + n.Dot(dotCmd, "") + } + }) + } +} + +var goTests = []struct { + src, dot, err string + skip bool +}{{ // #00 + src: "", + dot: `digraph ast { 0 [label=""]; }`, +}, { // #01 + src: "12", + dot: `digraph ast { 0 [label=""]; 1 [label="12"]; 0 -> 1; }`, +}, { // #02 + src: "1 + 2", + dot: `digraph ast { 0 [label=""]; 1 [label="+"]; 0 -> 1; 2 [label="1"]; 1 -> 2; 3 [label="2"]; 1 -> 3; }`, +}, { // #03 + src: "1 + 2 * 3", + dot: `digraph ast { 0 [label=""]; 1 [label="+"]; 0 -> 1; 2 [label="1"]; 1 -> 2; 3 [label="*"]; 1 -> 3; 4 [label="2"]; 3 -> 4; 5 [label="3"]; 3 -> 5; }`, +}, { // #04 + src: "1 * 2 + 3", + dot: `digraph ast { 0 [label=""]; 1 [label="+"]; 0 -> 1; 2 [label="*"]; 1 -> 2; 3 [label="1"]; 2 -> 3; 4 [label="2"]; 2 -> 4; 5 [label="3"]; 1 -> 5; }`, +}, { // #05 + src: "a := 2 + 5", + dot: `digraph ast { 0 [label=""]; 1 [label=":="]; 0 -> 1; 2 [label="a"]; 1 -> 2; 3 [label="+"]; 1 -> 3; 4 [label="2"]; 3 -> 4; 5 [label="5"]; 3 -> 5; }`, +}, { // #06 + src: "a := 1 * 2 + 3", + dot: `digraph ast { 0 [label=""]; 1 [label=":="]; 0 -> 1; 2 [label="a"]; 1 -> 2; 3 [label="+"]; 1 -> 3; 4 [label="*"]; 3 -> 4; 5 [label="1"]; 4 -> 5; 6 [label="2"]; 4 -> 6; 7 [label="3"]; 3 -> 7; }`, +}, { // #07 + src: "a := 1 + 2 * 3", + dot: `digraph ast { 0 [label=""]; 1 [label=":="]; 0 -> 1; 2 [label="a"]; 1 -> 2; 3 [label="+"]; 1 -> 3; 4 [label="1"]; 3 -> 4; 5 [label="*"]; 3 -> 5; 6 [label="2"]; 5 -> 6; 7 [label="3"]; 5 -> 7; }`, +}, { // #08 + src: "a := 1 + 2 * 3 + 4", + dot: `digraph ast { 0 [label=""]; 1 [label=":="]; 0 -> 1; 2 [label="a"]; 1 -> 2; 3 [label="+"]; 1 -> 3; 4 [label="1"]; 3 -> 4; 5 [label="+"]; 3 -> 5; 6 [label="*"]; 5 -> 6; 7 [label="2"]; 6 -> 7; 8 [label="3"]; 6 -> 8; 9 [label="4"]; 5 -> 9; }`, +}, { // #09 + src: "a := 1 + 2 + 3 * 4", + dot: `digraph ast { 0 [label=""]; 1 [label=":="]; 0 -> 1; 2 [label="a"]; 1 -> 2; 3 [label="+"]; 1 -> 3; 4 [label="1"]; 3 -> 4; 5 [label="+"]; 3 -> 5; 6 [label="2"]; 5 -> 6; 7 [label="*"]; 5 -> 7; 8 [label="3"]; 7 -> 8; 9 [label="4"]; 7 -> 9; }`, +}, { // #10 + src: "a := 1 * 2 + 3 * 4", + dot: `digraph ast { 0 [label=""]; 1 [label=":="]; 0 -> 1; 2 [label="a"]; 1 -> 2; 3 [label="+"]; 1 -> 3; 4 [label="*"]; 3 -> 4; 5 [label="1"]; 4 -> 5; 6 [label="2"]; 4 -> 6; 7 [label="*"]; 3 -> 7; 8 [label="3"]; 7 -> 8; 9 [label="4"]; 7 -> 9; }`, +}, { // #11 + src: "a := (1 + 2) * 3", + dot: `digraph ast { 0 [label=""]; 1 [label=":="]; 0 -> 1; 2 [label="a"]; 1 -> 2; 3 [label="*"]; 1 -> 3; 4 [label="(..)"]; 3 -> 4; 5 [label="+"]; 4 -> 5; 6 [label="1"]; 5 -> 6; 7 [label="2"]; 5 -> 7; 8 [label="3"]; 3 -> 8; }`, +}, { // #12 + src: "a := 2 * -3", + dot: `digraph ast { 0 [label=""]; 1 [label=":="]; 0 -> 1; 2 [label="a"]; 1 -> 2; 3 [label="*"]; 1 -> 3; 4 [label="2"]; 3 -> 4; 5 [label="-"]; 3 -> 5; 6 [label="3"]; 5 -> 6; }`, +}, { // #13 + src: "-5 + 4", + dot: `digraph ast { 0 [label=""]; 1 [label="+"]; 0 -> 1; 2 [label="-"]; 1 -> 2; 3 [label="5"]; 2 -> 3; 4 [label="4"]; 1 -> 4; }`, +}, { // #14 + src: "-5 + -4", + dot: `digraph ast { 0 [label=""]; 1 [label="+"]; 0 -> 1; 2 [label="-"]; 1 -> 2; 3 [label="5"]; 2 -> 3; 4 [label="-"]; 1 -> 4; 5 [label="4"]; 4 -> 5; }`, +}, { // #15 + src: "a := -5 + -4", + dot: `digraph ast { 0 [label=""]; 1 [label=":="]; 0 -> 1; 2 [label="a"]; 1 -> 2; 3 [label="+"]; 1 -> 3; 4 [label="-"]; 3 -> 4; 5 [label="5"]; 4 -> 5; 6 [label="-"]; 3 -> 6; 7 [label="4"]; 6 -> 7; }`, +}, { // #16 + src: "*a := 5 * -3", + dot: `digraph ast { 0 [label=""]; 1 [label=":="]; 0 -> 1; 2 [label="*"]; 1 -> 2; 3 [label="a"]; 2 -> 3; 4 [label="*"]; 1 -> 4; 5 [label="5"]; 4 -> 5; 6 [label="-"]; 4 -> 6; 7 [label="3"]; 6 -> 7; }`, +}, { // #17 + src: "*a := -5 * 3", + dot: `digraph ast { 0 [label=""]; 1 [label=":="]; 0 -> 1; 2 [label="*"]; 1 -> 2; 3 [label="a"]; 2 -> 3; 4 [label="*"]; 1 -> 4; 5 [label="-"]; 4 -> 5; 6 [label="5"]; 5 -> 6; 7 [label="3"]; 4 -> 7; }`, +}, { // #18 + src: "1+2\n3-4", + dot: `digraph ast { 0 [label=""]; 1 [label="+"]; 0 -> 1; 2 [label="1"]; 1 -> 2; 3 [label="2"]; 1 -> 3; 4 [label="-"]; 0 -> 4; 5 [label="3"]; 4 -> 5; 6 [label="4"]; 4 -> 6; }`, +}, { // #19 + src: "i = i+1", + dot: `digraph ast { 0 [label=""]; 1 [label="="]; 0 -> 1; 2 [label="i"]; 1 -> 2; 3 [label="+"]; 1 -> 3; 4 [label="i"]; 3 -> 4; 5 [label="1"]; 3 -> 5; }`, +}, { // #20 + src: "a[12] = 5", + dot: `digraph ast { 0 [label=""]; 1 [label="="]; 0 -> 1; 2 [label="a"]; 1 -> 2; 3 [label="[..]"]; 2 -> 3; 4 [label="12"]; 3 -> 4; 5 [label="5"]; 1 -> 5; }`, +}, { // #21 + src: "a[12][0] = 3", + dot: `digraph ast { 0 [label=""]; 1 [label="="]; 0 -> 1; 2 [label="a"]; 1 -> 2; 3 [label="[..]"]; 2 -> 3; 4 [label="12"]; 3 -> 4; 5 [label="[..]"]; 2 -> 5; 6 [label="0"]; 5 -> 6; 7 [label="3"]; 1 -> 7; }`, +}, { // #22 + src: "a.b = 34", + dot: `digraph ast { 0 [label=""]; 1 [label="="]; 0 -> 1; 2 [label="."]; 1 -> 2; 3 [label="a"]; 2 -> 3; 4 [label="b"]; 2 -> 4; 5 [label="34"]; 1 -> 5; }`, +}, { // #23 + src: "if i < 2 { return j }", + dot: `digraph ast { 0 [label=""]; 1 [label="if"]; 0 -> 1; 2 [label="<"]; 1 -> 2; 3 [label="i"]; 2 -> 3; 4 [label="2"]; 2 -> 4; 5 [label="{..}"]; 1 -> 5; 6 [label="return"]; 5 -> 6; 7 [label="j"]; 6 -> 7; }`, +}, { // #24 + src: "if i:=1; i < 2 { return j }", + dot: `digraph ast { 0 [label=""]; 1 [label="if"]; 0 -> 1; 2 [label=":="]; 1 -> 2; 3 [label="i"]; 2 -> 3; 4 [label="1"]; 2 -> 4; 5 [label="<"]; 1 -> 5; 6 [label="i"]; 5 -> 6; 7 [label="2"]; 5 -> 7; 8 [label="{..}"]; 1 -> 8; 9 [label="return"]; 8 -> 9; 10 [label="j"]; 9 -> 10; }`, +}, { // #25 + src: "f(i) + f(j)", + dot: `digraph ast { 0 [label=""]; 1 [label="+"]; 0 -> 1; 2 [label="Call"]; 1 -> 2; 3 [label="f"]; 2 -> 3; 4 [label="(..)"]; 2 -> 4; 5 [label="i"]; 4 -> 5; 6 [label="Call"]; 1 -> 6; 7 [label="f"]; 6 -> 7; 8 [label="(..)"]; 6 -> 8; 9 [label="j"]; 8 -> 9; }`, + //src: "f(i) + f(j)(4)", // not ok + /* + }, { // #26 + src: "if i < 2 {return i}; return f(i-2) + f(i-1)", + }, { // #27 + src: "for i < 2 { println(i) }", + }, { // #28 + src: "func f(i int) (int) { if i < 2 { return i}; return f(i-2) + f(i-1) }", + }, { // #29 + src: "a := []int{3, 4}", + }, { // #30 + //src: "a := struct{int}", + src: "a, b = c, d", + }, { // #31 + //src: "a := [2]int{3, 4}", + src: `fmt.Println("Hello")`, + //src: "(1 + 2) * (3 - 4)", + //src: "1 + (1 + 2)", + }, { // #32 + //src: `a(3)(4)`, + //src: `3 + 2 * a(3) + 5`, + //src: `3 + 2 * a(3)(4) + (5)`, + //src: `(a(3))(4)`, + src: `a(3)(4)`, + dot: `digraph ast { 0 [label=""]; 1 [label="Call"]; 0 -> 1; 2 [label="Call"]; 1 -> 2; 3 [label="a"]; 2 -> 3; 4 [label="(..)"]; 2 -> 4; 5 [label="3"]; 4 -> 5; 6 [label="(..)"]; 1 -> 6; 7 [label="4"]; 6 -> 7; }`, + //src: `println("Hello")`, + //src: `a.b.c + 3`, + }, { // #33 + src: `func f(a int, b int) {return a + b}; f(1+2)`, + }, { // #34 + src: `if a == 1 { + println(2) + } + println("bye")`, + */ +}} -- cgit v1.2.3