func (buffer *lexBuffer) factor() *types.TreeNode { var node *types.TreeNode var err error switch buffer.token.TokenType { case types.NUM: node = newExpNode(types.ConstK, buffer.token.Lineno) if buffer.token.TokenType == types.NUM { node.Val, err = strconv.Atoi(buffer.token.TokenString) if err != nil { panic(err) } } buffer.match(types.NUM) case types.ID: node = newExpNode(types.IdK, buffer.token.Lineno) if buffer.token.TokenType == types.ID { node.Name = buffer.token.TokenString } buffer.match(types.ID) case types.STRING: node = newExpNode(types.StringK, buffer.token.Lineno) node.ValString = buffer.token.TokenString buffer.match(types.STRING) case types.LPAREN: buffer.match(types.LPAREN) node = buffer.exp() buffer.match(types.RPAREN) default: syntaxError(buffer.token) } return node }
func (buffer *lexBuffer) lexSequence() *types.TreeNode { var node, p, q *types.TreeNode = nil, nil, nil for buffer.token.TokenType != types.ENDFILE { if buffer.token.TokenType == types.END || buffer.token.TokenType == types.ELSE || buffer.token.TokenType == types.UNTIL { buffer.nextToken() } if buffer.token.TokenType == types.ENDFILE { break } p = buffer.stmtSequence() if node == nil { node = p } else { q = node for q.Sibling != nil { q = q.Sibling } q.Sibling = p } } return node }
func checkNode(buf *buffer, node *types.TreeNode) { switch node.Node { case types.ExpK: if node.Exp == types.OpK { if node.Children[0].Type != types.Integer || node.Children[1].Type != types.Integer { typeError(node.Lineno, locale.Locale.AnalyzeTypeOpError) } if node.Op == types.EQ || node.Op == types.LT { node.Type = types.Boolean } else { node.Type = types.Integer } } else if node.Exp == types.ConstK || node.Exp == types.IdK { node.Type = types.Integer } else if node.Exp == types.StringK { node.Type = types.String } case types.StmtK: switch node.Stmt { case types.IfK: if node.Children[0].Type == types.Integer { typeError(node.Lineno, locale.Locale.AnalyzeTypeIfError) } case types.AssignK: if node.Children[0].Type != types.Integer { typeError(node.Lineno, locale.Locale.AnalyzeTypeAssignError) } case types.WriteK: if node.Children[0].Type != types.Integer && node.Children[0].Type != types.String { typeError(node.Lineno, locale.Locale.AnalyzeTypeWriteError) } case types.RepeatK: if node.Children[0].Type == types.Integer { typeError(node.Lineno, locale.Locale.AnalyzeTypeRepeatError) } } } }
func newExpNode(kind types.ExpKind, lineno int) *types.TreeNode { node := new(types.TreeNode) node.Children = make([]*types.TreeNode, 0, 0) node.Sibling = nil node.Node = types.ExpK node.Exp = kind node.Lineno = lineno return node }