summaryrefslogtreecommitdiff
path: root/parser
diff options
context:
space:
mode:
authorMarc Vertes <mvertes@free.fr>2023-09-01 11:42:55 +0200
committerMarc Vertes <mvertes@free.fr>2023-09-01 11:42:55 +0200
commit459eca16816023fb0afdd6e0948e5406d84e5bc5 (patch)
treeb752b860d92af8421614d2d147ea953e85a25871 /parser
parent851c793da43be9e4d3319afe440d603c85834045 (diff)
parser: skip comment modes
Refctor node kind names by concatenating category and instance, to allow better sorting. Comments are now parsed and skipped during generation of AST.
Diffstat (limited to 'parser')
-rw-r--r--parser/README.md2
-rw-r--r--parser/kind.go68
-rw-r--r--parser/parse.go11
-rw-r--r--parser/parse_test.go45
4 files changed, 77 insertions, 49 deletions
diff --git a/parser/README.md b/parser/README.md
index 2a25fc8..1c02d22 100644
--- a/parser/README.md
+++ b/parser/README.md
@@ -53,7 +53,7 @@ A successful test must be provided to check the status.
- [ ] full `if` statement (including `else`, `else if`)
- [x] init expressions in `if` statements
- [x] statement blocks
-- [ ] comments
+- [x] comments
- [ ] for statement
- [ ] switch statement
- [ ] select statement
diff --git a/parser/kind.go b/parser/kind.go
index d570358..d004471 100644
--- a/parser/kind.go
+++ b/parser/kind.go
@@ -2,46 +2,50 @@ package parser
import "fmt"
+// kind defines the AST node kind. Its name is the concatenation
+// of a category (Block, Decl, Expr, Op, Stmt) and an instance name.
type Kind int
const (
Undefined = Kind(iota)
- FuncDecl
- CallExpr
- IfStmt
- StmtBloc
- ReturnStmt
+ BlockParen
+ BlockStmt
+ Comment
+ DeclFunc
+ ExprCall
Ident
- StringLit
- NumberLit
- ParBloc
- DotOp
- MulOp
- AddOp
- SubOp
- AssignOp
- DefOp
- InfOp
+ LiteralNumber
+ LiteralString
+ OpAdd
+ OpAssign
+ OpDefine
+ OpDot
+ OpInferior
+ OpMultiply
+ OpSubtract
+ StmtIf
+ StmtReturn
)
var kindString = [...]string{
- Undefined: "Undefined",
- FuncDecl: "FuncDecl",
- CallExpr: "CallExpr",
- IfStmt: "IfStmt",
- StmtBloc: "StmtBloc",
- ReturnStmt: "ReturnStmt",
- Ident: "Ident",
- StringLit: "StringLit",
- NumberLit: "NumberLit",
- ParBloc: "ParBloc",
- DotOp: "DotOp",
- MulOp: "MulOp",
- AddOp: "AddOP",
- SubOp: "SubOp",
- AssignOp: "AssignOp",
- DefOp: "DefOp",
- InfOp: "InfOp",
+ Undefined: "Undefined",
+ BlockParen: "BlockParen",
+ BlockStmt: "BlockStmt",
+ Comment: "Comment",
+ DeclFunc: "DeclFunc",
+ ExprCall: "ExprCall",
+ Ident: "Ident",
+ LiteralString: "LiteralString",
+ LiteralNumber: "LiteralNumber",
+ OpAdd: "OpAdd",
+ OpAssign: "OpAssign",
+ OpDefine: "OpDefine",
+ OpDot: "OpDot",
+ OpInferior: "OpInferior",
+ OpMultiply: "OpMultiply",
+ OpSubtract: "OpSubtract",
+ StmtIf: "StmtIf",
+ StmtReturn: "StmtReturn",
}
func (k Kind) String() string {
diff --git a/parser/parse.go b/parser/parse.go
index 4f186bd..08fbdbd 100644
--- a/parser/parse.go
+++ b/parser/parse.go
@@ -1,6 +1,8 @@
package parser
-import "github.com/gnolang/parscan/scanner"
+import (
+ "github.com/gnolang/parscan/scanner"
+)
const (
Stmt = 1 << iota
@@ -43,13 +45,16 @@ func (p *Parser) ParseTokens(tokens []scanner.Token) (roots []*Node, err error)
Token: t,
Kind: p.Spec[t.Name()].Kind,
}
+ if c.Kind == Comment {
+ continue
+ }
if t.IsOperator() && (i == 0 || tokens[i-1].IsOperator()) {
unaryOp[c] = true
}
if c.Kind == Undefined {
switch t.Kind() {
case scanner.Number:
- c.Kind = NumberLit
+ c.Kind = LiteralNumber
case scanner.Identifier:
c.Kind = Ident
}
@@ -80,7 +85,7 @@ func (p *Parser) ParseTokens(tokens []scanner.Token) (roots []*Node, err error)
}
lce.Child = []*Node{{Token: lce.Token, Child: lce.Child, Kind: lce.Kind}}
lce.Token = scanner.NewToken("Call", c.Pos())
- lce.Kind = CallExpr
+ lce.Kind = ExprCall
}
}
tcont := t.Content()
diff --git a/parser/parse_test.go b/parser/parse_test.go
index d13f893..0a41d09 100644
--- a/parser/parse_test.go
+++ b/parser/parse_test.go
@@ -1,6 +1,7 @@
package parser
import (
+ "log"
"os"
"testing"
@@ -45,27 +46,42 @@ var GoScanner = &scanner.Scanner{
"`": "`",
"//": "\n",
},
+ BlockProp: map[string]uint{
+ "(": scanner.CharBlock,
+ "{": scanner.CharBlock,
+ "[": scanner.CharBlock,
+ `"`: scanner.CharStr | scanner.StrEsc | scanner.StrNonl,
+ "`": scanner.CharStr,
+ "'": scanner.CharStr | scanner.StrEsc,
+ "/*": scanner.CharStr,
+ "//": scanner.CharStr | scanner.ExcludeEnd | scanner.EosValidEnd,
+ },
}
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},
- "if": {IfStmt, Stmt | ExprSep, 0},
- "func": {FuncDecl, Decl | Call, 0},
- "return": {ReturnStmt, Stmt, 0},
- "{..}": {StmtBloc, ExprSep, 0},
- "(..)": {ParBloc, Call, 0},
+ ".": {Kind: OpDot, Flags: Call, Order: 3},
+ "*": {Kind: OpMultiply, Order: 4},
+ "+": {Kind: OpAdd, Order: 5},
+ "-": {Kind: OpSubtract, Order: 5},
+ "<": {Kind: OpInferior, Order: 6},
+ ":=": {Kind: OpDefine, Order: 7},
+ "=": {Kind: OpAssign, Order: 7},
+ "if": {Kind: StmtIf, Flags: Stmt | ExprSep},
+ "func": {Kind: DeclFunc, Flags: Decl | Call},
+ "return": {Kind: StmtReturn, Flags: Stmt},
+ "{..}": {Kind: BlockStmt, Flags: ExprSep},
+ "(..)": {Kind: BlockParen, Flags: Call},
+ "//..": {Kind: Comment},
+ "/*..": {Kind: Comment},
},
}
-func init() { GoParser.Init() }
+func init() {
+ GoParser.Init()
+ log.SetFlags(log.Lshortfile)
+}
func TestParse(t *testing.T) {
for _, test := range goTests {
@@ -173,6 +189,9 @@ var goTests = []struct {
}, { // #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; }`,
+}, { // #26
+ src: "a := 1 // This is a comment",
+ dot: `digraph ast { 0 [label=""]; 1 [label=":="]; 0 -> 1; 2 [label="a"]; 1 -> 2; 3 [label="1"]; 1 -> 3; }`,
//src: "f(i) + f(j)(4)", // not ok
/*
}, { // #26