Browse Source

make more progress with ast parsing

master
Brett Langdon 10 years ago
parent
commit
c08c817e79
3 changed files with 232 additions and 1 deletions
  1. +90
    -0
      ast/expressions.go
  2. +2
    -1
      ast/nodes.go
  3. +140
    -0
      parser/parser.go

+ 90
- 0
ast/expressions.go View File

@ -18,3 +18,93 @@ func NewTestListStarExpression() *TestlistStarExpression {
func (node *TestlistStarExpression) SetChild(n TestlistStarExpressionChildNode) { func (node *TestlistStarExpression) SetChild(n TestlistStarExpressionChildNode) {
node.ParentNode.SetChild(n) node.ParentNode.SetChild(n)
} }
type ComparisonChildNode interface {
Node
comparisonChild()
}
type Comparison struct {
ListNode
}
func NewComparison() *Comparison {
node := &Comparison{}
node.initBaseNode(COMPARISON)
return node
}
func (node *Comparison) notTestChild() {}
func (node *Comparison) Append(n ComparisonChildNode) { node.ListNode.Append(n) }
type ExpressionChildNode interface {
Node
expressionChild()
}
type Expression struct {
ListNode
}
func NewExpression() *Expression {
node := &Expression{}
node.initBaseNode(EXPR)
return node
}
func (node *Expression) comparisonChild() {}
func (node *Expression) Append(n ExpressionChildNode) { node.ListNode.Append(n) }
type XorExpressionChildNode interface {
Node
xorExpressionChild()
}
type XorExpression struct {
ListNode
}
func NewXorExpression() *XorExpression {
node := &XorExpression{}
node.initBaseNode(XOR_EXPR)
return node
}
func (node *XorExpression) expressionChild() {}
func (node *XorExpression) Append(n XorExpressionChildNode) { node.ListNode.Append(n) }
type AndExpressionChildNode interface {
Node
andExpressionChild()
}
type AndExpression struct {
ListNode
}
func NewAndExpression() *AndExpression {
node := &AndExpression{}
node.initBaseNode(AND_EXPR)
return node
}
func (node *AndExpression) xorExpressionChild() {}
func (node *AndExpression) Append(n AndExpressionChildNode) { node.ListNode.Append(n) }
type ShiftExpressionChildNode interface {
Node
shiftExpressionChild()
}
type ShiftExpression struct {
ListNode
}
func NewShiftExpression() *ShiftExpression {
node := &ShiftExpression{}
node.initBaseNode(SHIFT_EXPR)
return node
}
func (node *ShiftExpression) andExpressionChild() {}
func (node *ShiftExpression) Append(n ShiftExpressionChildNode) { node.ListNode.Append(n) }

+ 2
- 1
ast/nodes.go View File

@ -16,7 +16,8 @@ func NewTokenNode(tok *token.Token) *TokenNode {
Token: tok, Token: tok,
} }
} }
func (node *TokenNode) Name() string { return token.TokenNames[node.Token.ID] }
func (node *TokenNode) comparisonChild() {}
func (node *TokenNode) Name() string { return token.TokenNames[node.Token.ID] }
func (node *TokenNode) Repr() []interface{} { func (node *TokenNode) Repr() []interface{} {
parts := make([]interface{}, 0) parts := make([]interface{}, 0)
parts = append(parts, node.Name()) parts = append(parts, node.Name())


+ 140
- 0
parser/parser.go View File

@ -62,9 +62,149 @@ func (parser *Parser) parseCompoundStatement() *ast.CompoundStatement {
return compoundStmt return compoundStmt
} }
// shift_expr: arith_expr (('<<'|'>>') arith_expr)*
func (parser *Parser) parseShiftExpression() *ast.ShiftExpression {
expr := ast.NewShiftExpression()
return expr
}
// and_expr: shift_expr ('&' shift_expr)*
func (parser *Parser) parseAndExpression() *ast.AndExpression {
expr := ast.NewAndExpression()
shiftExpr := parser.parseShiftExpression()
if shiftExpr == nil {
return nil
}
expr.Append(shiftExpr)
for {
next := parser.nextToken()
if next.ID != token.AMPER {
parser.unreadToken(next)
break
}
shiftExpr := parser.parseShiftExpression()
if shiftExpr == nil {
return nil
}
expr.Append(shiftExpr)
}
return expr
}
// xor_expr: and_expr ('^' and_expr)*
func (parser *Parser) parseXorExpression() *ast.XorExpression {
expr := ast.NewXorExpression()
andExpr := parser.parseAndExpression()
if andExpr == nil {
return nil
}
expr.Append(andExpr)
for {
next := parser.nextToken()
if next.ID != token.CIRCUMFLEX {
parser.unreadToken(next)
break
}
andExpr := parser.parseAndExpression()
if andExpr == nil {
return nil
}
expr.Append(andExpr)
}
return expr
}
// expr: xor_expr ('|' xor_expr)*
func (parser *Parser) parseExpression() *ast.Expression {
expr := ast.NewExpression()
xorExpr := parser.parseXorExpression()
if xorExpr == nil {
return nil
}
expr.Append(xorExpr)
for {
next := parser.nextToken()
if next.ID != token.VBAR {
parser.unreadToken(next)
break
}
xorExpr := parser.parseXorExpression()
if xorExpr == nil {
return nil
}
expr.Append(xorExpr)
}
return expr
}
// comparison: expr (comp_op expr)*
func (parser *Parser) parseComparison() *ast.Comparison {
comparison := ast.NewComparison()
expr := parser.parseExpression()
if expr == nil {
return nil
}
comparison.Append(expr)
for {
// comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
compOp := true
next := parser.nextToken()
switch next.Literal {
case "<", ">", "==", ">=", "<=", "<>", "!=", "in":
comparison.Append(ast.NewTokenNode(next))
case "is":
comparison.Append(ast.NewTokenNode(next))
next2 := parser.nextToken()
if next2.Literal == "not" {
comparison.Append(ast.NewTokenNode(next2))
} else {
parser.unreadToken(next2)
}
case "not":
next2 := parser.nextToken()
if next2.Literal == "in" {
comparison.Append(ast.NewTokenNode(next))
comparison.Append(ast.NewTokenNode(next2))
} else {
parser.unreadToken(next2)
parser.unreadToken(next)
compOp = false
}
default:
parser.unreadToken(next)
compOp = false
}
if compOp == false {
break
}
expr := parser.parseExpression()
if expr == nil {
return nil
}
comparison.Append(expr)
}
return comparison
}
// not_test: 'not' not_test | comparison // not_test: 'not' not_test | comparison
func (parser *Parser) parseNotTest() *ast.NotTest { func (parser *Parser) parseNotTest() *ast.NotTest {
notTest := ast.NewNotTest() notTest := ast.NewNotTest()
next := parser.nextToken()
if next.IsLiteral("not") {
test := parser.parseNotTest()
if test == nil {
return nil
}
notTest.SetChild(test)
} else {
comparison := parser.parseComparison()
if comparison == nil {
return nil
}
notTest.SetChild(comparison)
}
return notTest return notTest
} }


Loading…
Cancel
Save