Browse Source

add parsing of or test and or test

master
Brett Langdon 10 years ago
parent
commit
c407f08d6f
2 changed files with 81 additions and 3 deletions
  1. +21
    -2
      ast/tests.go
  2. +60
    -1
      parser/parser.go

+ 21
- 2
ast/tests.go View File

@ -6,7 +6,7 @@ type TestChildNode interface {
}
type Test struct {
ParentNode
ListNode
}
func NewTest() *Test {
@ -16,7 +16,8 @@ func NewTest() *Test {
}
func (node *Test) testlistStarExpressionChild() {}
func (node *Test) SetChild(n TestChildNode) { node.ParentNode.SetChild(n) }
func (node *Test) testChild() {}
func (node *Test) Append(n TestChildNode) { node.ListNode.Append(n) }
type OrTestChildNode interface {
Node
@ -35,3 +36,21 @@ func NewOrTest() *OrTest {
func (node *OrTest) testChild() {}
func (node *OrTest) Append(n OrTestChildNode) { node.ListNode.Append(n) }
type AndTestChildNode interface {
Node
andTestChild()
}
type AndTest struct {
ListNode
}
func NewAndTest() *AndTest {
node := &AndTest{}
node.initBaseNode(AND_TEST)
return node
}
func (node *AndTest) orTestChild() {}
func (node *AndTest) Append(n AndTestChildNode) { node.ListNode.Append(n) }

+ 60
- 1
parser/parser.go View File

@ -36,12 +36,24 @@ func (parser *Parser) addError(msg string) {
})
}
func (parser *Parser) expect(tokID token.TokenID) {
func (parser *Parser) expect(tokID token.TokenID) bool {
next := parser.nextToken()
if next.ID != tokID {
msg := "Unexpected token \"" + next.ID.String() + "\" expected \"" + tokID.String() + "\""
parser.addError(msg)
return false
}
return true
}
func (parser *Parser) expectLiteral(literal string) bool {
next := parser.nextToken()
if next.ID != token.NAME || next.Literal != literal {
msg := "Unexpected literal \"" + next.Literal + "\" expected \"" + literal + "\""
parser.addError(msg)
return false
}
return true
}
// compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated | async_stmt
@ -50,15 +62,62 @@ func (parser *Parser) parseCompoundStatement() *ast.CompoundStatement {
return compoundStmt
}
// and_test: not_test ('and' not_test)*
func (parser *Parser) parseAndTest() *ast.AndTest {
andTest := ast.NewAndTest()
return andTest
}
// or_test: and_test ('or' and_test)*
func (parser *Parser) parseOrTest() *ast.OrTest {
orTest := ast.NewOrTest()
andTest := parser.parseAndTest()
if andTest == nil {
return nil
}
orTest.Append(andTest)
for {
next := parser.nextToken()
if next.ID != token.NAME || next.Literal != "and" {
parser.unreadToken(next)
break
}
andTest = parser.parseAndTest()
if andTest == nil {
return nil
}
orTest.Append(andTest)
}
return orTest
}
// test: or_test ['if' or_test 'else' test] | lambdef
func (parser *Parser) parseTest() *ast.Test {
test := ast.NewTest()
orTest := parser.parseOrTest()
if orTest != nil {
test.Append(orTest)
next := parser.nextToken()
// Do not use `parser.expectLiteral`, this next part is optional
if next.ID == token.NAME && next.Literal == "if" {
orTest = parser.parseOrTest()
if orTest != nil {
test.Append(orTest)
if parser.expectLiteral("else") {
elseTest := parser.parseTest()
if elseTest == nil {
return nil
}
test.Append(test)
}
}
} else {
parser.unreadToken(next)
}
} else {
// TODO: parser.parseLambDef()
}
return test
}


Loading…
Cancel
Save