v/vlib/compiler2/parser/parser.v

139 lines
2.3 KiB
V
Raw Normal View History

2019-12-22 02:34:37 +01:00
// 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:
2019-12-24 18:54:43 +01:00
tok token.Token
lit string
2019-12-22 02:34:37 +01:00
}
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()
return p.expr(token.lowest_prec)
2019-12-22 02:34:37 +01:00
}
2019-12-24 18:54:43 +01:00
pub fn parse_stmt(text string) ast.Stmt {
mut s := scanner.new_scanner(text)
res := s.scan()
mut p := Parser{
scanner: s
tok: res.tok
lit: res.lit
}
return p.stmt()
}
2019-12-22 02:34:37 +01:00
fn (p mut Parser) next() {
res := p.scanner.scan()
p.tok = res.tok
2019-12-24 18:54:43 +01:00
// println(p.tok.str())
2019-12-22 02:34:37 +01:00
p.lit = res.lit
}
// Implementation of Pratt Precedence
pub fn (p mut Parser) expr(rbp int) ast.Expr {
// null denotation (prefix)
tok := p.tok
lit := p.lit
p.next()
2019-12-26 10:02:38 +01:00
mut node := ast.Expr{}
match tok {
.lpar {
2019-12-24 18:54:43 +01:00
node = p.expr(0)
if p.tok != .rpar {
2019-12-24 18:54:43 +01:00
panic('Parse Error: expected )')
}
p.next()
2019-12-22 02:34:37 +01:00
}
else {
// TODO: fix bug. note odd conditon instead of else if (same below)
if tok.is_scalar() {
2019-12-26 11:21:41 +01:00
if tok == .str {
node = ast.StringLiteral {
val: lit
}
} if tok == .number {
node = ast.IntegerLiteral {
val: lit.int()
}
2019-12-24 18:54:43 +01:00
}
2019-12-26 11:21:41 +01:00
//else {
//verror('bad scalar token')
//}
}
if !tok.is_scalar() && tok.is_unary() {
2019-12-24 18:54:43 +01:00
node = ast.UnaryExpr{
left: p.expr(token.highest_prec)
op: tok
}
}
2019-12-24 18:54:43 +01:00
}}
// left binding power
for rbp < p.tok.precedence() {
tok2 := p.tok
2019-12-22 02:34:37 +01:00
p.next()
// left denotation (infix)
if tok2.is_right_assoc() {
2019-12-24 18:54:43 +01:00
node = ast.BinaryExpr{
left: node
op: tok2
right: p.expr(tok2.precedence() - 1)
}
}
if !tok2.is_right_assoc() && tok2.is_left_assoc() {
2019-12-24 18:54:43 +01:00
node = ast.BinaryExpr{
left: node
op: tok2
right: p.expr(tok2.precedence())
}
}
2019-12-22 02:34:37 +01:00
}
2019-12-24 18:54:43 +01:00
return node
}
fn (p mut Parser) stmt() ast.Stmt {
if p.tok == .name {
name := p.lit
p.next()
if p.tok == .decl_assign {
p.next()
return ast.VarDecl{
name: name
expr: p.expr(token.lowest_prec)
}
}
}
/*
match node {
Ident {
}
}
*/
2019-12-26 10:02:38 +01:00
return ast.VarDecl{}
2019-12-22 02:34:37 +01:00
}
2019-12-26 11:21:41 +01:00
fn verror(s string) {
println(s)
exit(1)
}