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 void ParseDeclaration() { while (scan.Peek().type == Token.Type.SEMICOLON) { scan.Read(); } if (scan.Peek().type == Token.Type.EOF) { return; } Token first_token = scan.Peek(); Symbols.Type type = ParseTypeSpecifier(), variable_type = null; Pair <Symbols.Var, Pair <Symbols.RefType, Symbols.RefType> > pair = null; bool function = true; while (true) { variable_type = type; if ((pair = ParseDeclarator()) != null) { if (pair.last != null) { pair.last.last.SetType(type); variable_type = pair.last.first; } ///Когда мы устанавливаем финальный тип, то нужно пересчитать размер всех типов if (pair.first == null && !(variable_type is Symbols.RECORD)) { throw new Syntax.Exception("требуется идентификатор", scan.GetPos(), scan.GetLine()); } if (pair.first != null) { pair.first.SetType(variable_type); } if (scan.Peek().type == Token.Type.OP_ASSIGN) // init declarator { Symbols.Var v = pair.first; Syntax.Expression node = new Syntax.Identifier( new Token(v.GetIndex(), v.GetLine(), Token.Type.IDENTIFICATOR, v.GetName()), v ); node = ParseBinaryOper(0, node, true); //pair.first.SetInitializer(ParseInitializer()); pair.first.SetInitializer(node); function = false; } if (function && scan.Peek().type == Token.Type.LBRACE && tstack.IsGlobal()) { pair.last.first.SetName(pair.first.GetName()); tstack.AddSymbol(pair.first); tstack.NewTable(); if (((Symbols.Func)pair.last.first).GetArguments() .Count(x => x.GetName() == pair.first.GetName()) == 0) { tstack.AddSymbol(pair.first); } foreach (Symbols.Var arg in ((Symbols.Func)pair.last.first).GetArguments()) { tstack.AddSymbol(arg); } this.ret_func_type = ((Symbols.Func)pair.last.first).GetRefType(); ((Symbols.Func)pair.last.first).SetBody(ParseCompound(false)); tstack.GetCurrentTable().RemoveSymbol(pair.first); ((Symbols.Func)pair.last.first).SetTable(tstack.PopTable()); } else { function = false; } if (!function && variable_type is Symbols.VOID) { throw new Symbols.Exception("недопустимо использование типа \"void\"", first_token.GetIndex(), first_token.GetLine()); } if (pair.first != null && !function) { try { tstack.AddSymbol(pair.first); } catch (Symbols.Exception e) { this.logger.Add(e); } } } if (scan.Peek().type != Token.Type.COMMA || function) { break; } scan.Read(); function = false; } if (!function) { CheckToken(scan.Peek(), Token.Type.SEMICOLON, true); } }