mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
new AST built with sum types
This commit is contained in:
81
vlib/compiler2/parser/parser.v
Normal file
81
vlib/compiler2/parser/parser.v
Normal file
@@ -0,0 +1,81 @@
|
||||
// Copyright (c) 2019 Alexander Medvednikov. All rights reserved.
|
||||
// Use of this source code is governed by an MIT license
|
||||
// that can be found in the LICENSE file.
|
||||
module parser
|
||||
|
||||
import (
|
||||
compiler2.scanner
|
||||
compiler2.ast
|
||||
compiler2.token
|
||||
)
|
||||
|
||||
struct Parser {
|
||||
scanner &scanner.Scanner
|
||||
mut:
|
||||
tok token.Token
|
||||
lit string
|
||||
}
|
||||
|
||||
pub fn parse_expr(text string) ast.Expr {
|
||||
mut s := scanner.new_scanner(text)
|
||||
res := s.scan()
|
||||
mut p := Parser{
|
||||
scanner: s
|
||||
tok: res.tok
|
||||
lit: res.lit
|
||||
}
|
||||
return p.expr()
|
||||
}
|
||||
|
||||
fn (p mut Parser) next() {
|
||||
res := p.scanner.scan()
|
||||
p.tok = res.tok
|
||||
//println(p.tok.str())
|
||||
p.lit = res.lit
|
||||
}
|
||||
|
||||
fn (p mut Parser) expr() ast.Expr {
|
||||
//println('\n\nexpr()')
|
||||
mut node := p.term()
|
||||
for p.tok == .plus || p.tok == .minus {
|
||||
op := p.tok
|
||||
p.next()
|
||||
node = ast.BinaryExpr {
|
||||
left: node
|
||||
op: op
|
||||
right: p.term()
|
||||
}
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
fn (p mut Parser) term() ast.Expr {
|
||||
mut node := p.factor()
|
||||
for p.tok == .mul || p.tok == .div || p.tok == .mod {
|
||||
op := p.tok
|
||||
p.next()
|
||||
node = ast.BinaryExpr {
|
||||
left: node
|
||||
op: op
|
||||
right: p.factor()
|
||||
}
|
||||
}
|
||||
return node
|
||||
//return ast.BinaryExpr{}
|
||||
//return ast.Expr.Binary(ast.BinaryExpr{})
|
||||
}
|
||||
|
||||
fn (p mut Parser) factor() ast.Expr {
|
||||
if p.tok == .number {
|
||||
val := p.lit.int()
|
||||
p.next()
|
||||
return ast.IntegerExpr { val: val }
|
||||
} else {
|
||||
println('bad factor token')
|
||||
println(p.tok)
|
||||
exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
35
vlib/compiler2/parser/parser_test.v
Normal file
35
vlib/compiler2/parser/parser_test.v
Normal file
@@ -0,0 +1,35 @@
|
||||
module parser
|
||||
|
||||
import compiler2.ast
|
||||
|
||||
fn test_parser() {
|
||||
//expr := ast.IntegerExpr {val:10}
|
||||
//expr := ast.BinaryExpr{}
|
||||
expr := parse_expr('3 + 7')
|
||||
walk(expr)
|
||||
println('')
|
||||
}
|
||||
|
||||
fn walk(node ast.Expr) {
|
||||
//println('walk()')
|
||||
match node {
|
||||
ast.IntegerExpr {
|
||||
print(it.val)
|
||||
}
|
||||
ast.BinaryExpr {
|
||||
walk(it.left)
|
||||
match it.op {
|
||||
.plus {
|
||||
print(' + ')
|
||||
}
|
||||
.minus {
|
||||
print(' - ')
|
||||
}
|
||||
else {}
|
||||
|
||||
}
|
||||
walk(it.right)
|
||||
}
|
||||
else {}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user