Browse Source

get working on the parser

master
Brett Langdon 10 years ago
parent
commit
8de9bd86d6
1 changed files with 99 additions and 5 deletions
  1. +99
    -5
      parser/parser.go

+ 99
- 5
parser/parser.go View File

@ -10,8 +10,8 @@ import (
) )
type Parser struct { type Parser struct {
tokenizer *scanner.Scanner
Errors []*Error
tokenizer *scanner.Scanner
tokenBuffer []*token.Token tokenBuffer []*token.Token
} }
@ -30,6 +30,92 @@ func (parser *Parser) unreadToken(tok *token.Token) {
parser.tokenBuffer = append(parser.tokenBuffer, tok) parser.tokenBuffer = append(parser.tokenBuffer, tok)
} }
func (parser *Parser) addError(msg string) {
parser.Errors = append(parser.Errors, &Error{
Message: msg,
})
}
func (parser *Parser) expect(tokID token.TokenID) {
next := parser.nextToken()
if next.ID != tokID {
msg := "Unexpected token \"" + next.ID.String() + "\" expected \"" + tokID.String() + "\""
parser.addError(msg)
}
}
// compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated | async_stmt
func (parser *Parser) parseCompoundStatement() *ast.CompoundStatement {
compoundStmt := ast.NewCompoundStatement()
return compoundStmt
}
// expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
// ('=' (yield_expr|testlist_star_expr))*)
func (parser *Parser) parseExpressionStatement() *ast.ExpressionStatement {
exprStmt := ast.NewExpressionStatement()
return exprStmt
}
// small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
// import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
func (parser *Parser) parseSmallStatment() *ast.SmallStatement {
smallStmt := ast.NewSmallStatement()
var stmt ast.SmallStatementNode
stmt = parser.parseExpressionStatement()
if stmt != nil {
smallStmt.Statement = stmt
}
if stmt == nil {
return nil
}
return smallStmt
}
// simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
func (parser *Parser) parseSimpleStatement() *ast.SimpleStatement {
simpleStmt := ast.NewSimpleStatement()
for {
smallStmt := parser.parseSmallStatment()
if smallStmt == nil {
break
}
simpleStmt.AppendSmallStatement(smallStmt)
next := parser.nextToken()
if next.ID != token.SEMI {
parser.unreadToken(next)
break
}
}
// no small statements found
if len(simpleStmt.Statements) == 0 {
return nil
}
parser.expect(token.NEWLINE)
return simpleStmt
}
// stmt: simple_stmt | compound_stmt
func (parser *Parser) parseStatement() *ast.Statement {
var next ast.StatementNode
next = parser.parseSimpleStatement()
if next == nil {
next = parser.parseCompoundStatement()
}
if next == nil {
return nil
}
stmt := ast.NewStatement()
stmt.Statement = next
return stmt
}
// file_input: (NEWLINE | stmt)* ENDMARKER
func (parser *Parser) parseFileInput() *ast.FileInput { func (parser *Parser) parseFileInput() *ast.FileInput {
root := ast.NewFileInput() root := ast.NewFileInput()
for parser.tokenizer.State() == errorcode.E_OK { for parser.tokenizer.State() == errorcode.E_OK {
@ -37,22 +123,30 @@ func (parser *Parser) parseFileInput() *ast.FileInput {
if next.ID == token.NEWLINE { if next.ID == token.NEWLINE {
root.AppendToken(next) root.AppendToken(next)
} else if next.ID == token.ENDMARKER { } else if next.ID == token.ENDMARKER {
// Unread, so we can read in the expected value later
parser.unreadToken(next)
break break
} else { } else {
parser.unreadToken(next) parser.unreadToken(next)
// TODO: parser.parseStatement()
stmt := parser.parseStatement()
if stmt == nil {
break
}
root.AppendNode(stmt)
break break
} }
} }
parser.expect(token.ENDMARKER)
return root return root
} }
func ParseReader(r io.Reader) *ast.FileInput {
func ParseReader(r io.Reader) (*ast.FileInput, *Parser) {
parser := &Parser{ parser := &Parser{
tokenizer: scanner.NewScanner(r), tokenizer: scanner.NewScanner(r),
tokenBuffer: make([]*token.Token, 0), tokenBuffer: make([]*token.Token, 0),
} }
return parser.parseFileInput()
return parser.parseFileInput(), parser
} }

Loading…
Cancel
Save