private void InitTableStack() { tstack.AddSymbol(new Symbols.INT("int", 0, 0)); tstack.AddSymbol(new Symbols.CHAR("char", 0, 0)); tstack.AddSymbol(new Symbols.DOUBLE("double", 0, 0)); tstack.AddSymbol(new Symbols.VOID("void", 0, 0)); Symbols.ExternFunc f = new Symbols.ExternFunc("printf"); Symbols.GlobalVar v = new Symbols.GlobalVar("printf", 0, 0); Symbols.ParamVar str = new Symbols.ParamVar(); v.SetType(f); str.SetType(new Symbols.POINTER(new Symbols.CHAR())); f.AddArgument(str); f.SetUnspecifiedArgs(); tstack.AddSymbol(v); f = new Symbols.ExternFunc("scanf"); v = new Symbols.GlobalVar("scanf", 0, 0); v.SetType(f); f.AddArgument(str); f.SetUnspecifiedArgs(); tstack.AddSymbol(v); f = new Symbols.ExternFunc("getchar"); v = new Symbols.GlobalVar("getchar", 0, 0); v.SetType(f); f.SetType(new Symbols.INT()); tstack.AddSymbol(v); }
private Symbols.ParamVar ParseParameterDeclaration() { Token first_token = scan.Peek(); Symbols.Type type = ParseTypeSpecifier(); Symbols.ParamVar variable = null; if (type != null) { Pair <Symbols.Var, Pair <Symbols.RefType, Symbols.RefType> > res; res = ParseDeclarator(parse_parameter: true); variable = (Symbols.ParamVar)res.first; if (res.last != null) { res.last.last.SetType(type); type = res.last.first; } if (type is Symbols.VOID) { this.logger.Add(new Symbols.Exception("недопустимо использование типа \"void\"", first_token.GetIndex(), first_token.GetLine())); type = new Symbols.SuperType(); } if (variable == null) { variable = new Symbols.ParamVar("", type.GetIndex(), type.GetLine()); } } variable.SetType(type); return(variable); }
private List <Symbols.ParamVar> ParseParameterList() { List <Symbols.ParamVar> res = new List <Symbols.ParamVar>(); Symbols.ParamVar param = null; this.parse_args_declaraton = true; while (scan.Peek().type != Token.Type.RPAREN) { try { param = ParseParameterDeclaration(); } catch (Exception e) { ToHandlerException(e); continue; } if (param == null) { break; } res.Add(param); if (scan.Peek().type != Token.Type.COMMA) { break; } scan.Read(); } this.parse_args_declaraton = false; return(res); }
private Symbols.ParamVar ParseParameterDeclaration() { Token first_token = scan.Peek(); Symbols.Type type = ParseTypeSpecifier(); Symbols.ParamVar variable = null; if (type != null) { Pair<Symbols.Var, Pair<Symbols.RefType, Symbols.RefType>> res; res = ParseDeclarator(parse_parameter:true); variable = (Symbols.ParamVar)res.first; if (res.last != null) { res.last.last.SetType(type); type = res.last.first; } if (type is Symbols.VOID) { this.logger.Add(new Symbols.Exception("недопустимо использование типа \"void\"", first_token.GetIndex(), first_token.GetLine())); type = new Symbols.SuperType(); } if (variable == null) { variable = new Symbols.ParamVar("", type.GetIndex(), type.GetLine()); } } variable.SetType(type); return variable; }
private Pair<Symbols.Var, Pair<Symbols.RefType, Symbols.RefType>> ParseDirectDeclarator( bool parse_abstract = false, bool parse_parameter = false) { Symbols.Var variable = null; Pair<Symbols.RefType, Symbols.RefType> tpair = null; Symbols.RefType type = null; if (scan.Peek().type == Token.Type.IDENTIFICATOR && !parse_abstract) { if (parse_parameter) { variable = new Symbols.ParamVar(scan.Read()); } else if (tstack.IsGlobal()) { variable = new Symbols.GlobalVar(scan.Read()); } else { variable = new Symbols.LocalVar(scan.Read()); } } else if (scan.Peek().type == Token.Type.LPAREN) { scan.Read(); Pair<Symbols.Var, Pair<Symbols.RefType, Symbols.RefType>> res = ParseDeclarator(parse_abstract, parse_parameter); variable = res.first; if (res.last != null) { if (tpair == null) { tpair = new Pair<Symbols.RefType, Symbols.RefType>(res.last.first, res.last.last); } else { tpair.last.SetType(res.last.first); tpair.last = res.last.last; } } CheckToken(scan.Peek(), Token.Type.RPAREN, false); if (res.last == null && res.first == null) { throw new Syntax.Exception("требуется выражение", scan.GetPos(), scan.GetLine()); } scan.Read(); } bool ret = false; while (true) { if (scan.Peek().type == Token.Type.LBRACKET) { type = new Symbols.ARRAY(scan.Read()); ((Symbols.ARRAY)type).SetSize(ParseAssignmentExpression()); CheckToken(scan.Peek(), Token.Type.RBRACKET, true); } else if (scan.Peek().type == Token.Type.LPAREN) { type = new Symbols.Func("", scan.Peek().pos, scan.Peek().line); scan.Read(); tstack.NewTable(); ((Symbols.Func)type).SetArguments(ParseParameterList()); ((Symbols.Func)type).SetTable(tstack.PopTable()); CheckToken(scan.Peek(), Token.Type.RPAREN, true); } else { ret = true; } if (type != null ) { if (tpair != null) { tpair.last.SetType(type); tpair.last = type; } else { tpair = new Pair<Symbols.RefType, Symbols.RefType>(type, type); } } type = null; if (ret) { return new Pair<Symbols.Var, Pair<Symbols.RefType, Symbols.RefType>>(variable, tpair); } } }
private Syntax.Expression ParseUnaryExpr() { Syntax.UnaryOperator node = null; switch (scan.Peek().type) { case Token.Type.OP_INC: case Token.Type.OP_DEC: case Token.Type.OP_BIT_AND: case Token.Type.OP_STAR: case Token.Type.OP_PLUS: case Token.Type.OP_SUB: case Token.Type.OP_TILDE: case Token.Type.OP_NOT: node = new Syntax.UnaryOperator(scan.Read()); node.SetOperand(this.ParseUnaryExpr()); return(node); case Token.Type.LPAREN: Syntax.Expression res = null; Token t = scan.Read(); if (IsType(scan.Peek())) { res = new Syntax.Cast(t); Symbols.ParamVar var = ParseParameterDeclaration(); //this is hack ((Syntax.Cast)res).SetTypeCast(var.GetType()); CheckToken(scan.Peek(), Token.Type.RPAREN, true); ((Syntax.Cast)res).SetOperand(ParseUnaryExpr()); return(res); } res = ParseExpression(); CheckToken(scan.Peek(), Token.Type.RPAREN, true); return(ParsePostfixExpr(res)); case Token.Type.KW_SIZEOF: node = new Syntax.UnaryOperator(scan.Read()); if (scan.Peek().type != Token.Type.LPAREN) { node.SetOperand(ParseUnaryExpr()); return(node); } scan.Read(); if (IsType(scan.Peek())) { ((Syntax.UnaryOperator)node).SetOperand(new Syntax.Identifier(scan.Read())); } else { node.SetOperand(ParseExpression()); } CheckToken(scan.Peek(), Token.Type.RPAREN, true); return(node); default: return(ParsePostfixExpr()); } }
private Pair <Symbols.Var, Pair <Symbols.RefType, Symbols.RefType> > ParseDirectDeclarator( bool parse_abstract = false, bool parse_parameter = false) { Symbols.Var variable = null; Pair <Symbols.RefType, Symbols.RefType> tpair = null; Symbols.RefType type = null; if (scan.Peek().type == Token.Type.IDENTIFICATOR && !parse_abstract) { if (parse_parameter) { variable = new Symbols.ParamVar(scan.Read()); } else if (tstack.IsGlobal()) { variable = new Symbols.GlobalVar(scan.Read()); } else { variable = new Symbols.LocalVar(scan.Read()); } } else if (scan.Peek().type == Token.Type.LPAREN) { scan.Read(); Pair <Symbols.Var, Pair <Symbols.RefType, Symbols.RefType> > res = ParseDeclarator(parse_abstract, parse_parameter); variable = res.first; if (res.last != null) { if (tpair == null) { tpair = new Pair <Symbols.RefType, Symbols.RefType>(res.last.first, res.last.last); } else { tpair.last.SetType(res.last.first); tpair.last = res.last.last; } } CheckToken(scan.Peek(), Token.Type.RPAREN, false); if (res.last == null && res.first == null) { throw new Syntax.Exception("требуется выражение", scan.GetPos(), scan.GetLine()); } scan.Read(); } bool ret = false; while (true) { if (scan.Peek().type == Token.Type.LBRACKET) { type = new Symbols.ARRAY(scan.Read()); ((Symbols.ARRAY)type).SetSize(ParseAssignmentExpression()); CheckToken(scan.Peek(), Token.Type.RBRACKET, true); } else if (scan.Peek().type == Token.Type.LPAREN) { type = new Symbols.Func("", scan.Peek().pos, scan.Peek().line); scan.Read(); tstack.NewTable(); ((Symbols.Func)type).SetArguments(ParseParameterList()); ((Symbols.Func)type).SetTable(tstack.PopTable()); CheckToken(scan.Peek(), Token.Type.RPAREN, true); } else { ret = true; } if (type != null) { if (tpair != null) { tpair.last.SetType(type); tpair.last = type; } else { tpair = new Pair <Symbols.RefType, Symbols.RefType>(type, type); } } type = null; if (ret) { return(new Pair <Symbols.Var, Pair <Symbols.RefType, Symbols.RefType> >(variable, tpair)); } } }