private void ParseTypeDecl(SymTable symTable) { var c = Current; Require(Identifier); Require(Equal); var t = ParseType(symTable); switch (t) { case ArrayTypeSymbol at: at.Name = c.Value.ToString(); symTable.Add(at.Name, at); break; case RecordTypeSymbol rt: rt.Name = c.Value.ToString(); symTable.Add(rt.Name, rt); break; default: symTable.Add(c.Value.ToString(), t); break; } }
private Parameters ParseValueParameter(SymTable symTable) { List <string> idents = new List <string>(); while (Current.SubType == Identifier) { idents.Add(Current.Value.ToString()); Next(); if (Current.SubType != Comma) { break; } Next(); } Require(Colon); var t = Current; Require(Identifier); var tp = symTable.LookUp(t.Value.ToString()); if (!(tp is TypeSymbol)) { throw new ParserException("Illegal type declaration", t.Line, t.Position); } if (Current.SubType == Equal) { if (idents.Count != 1) { throw new ParserException("Only one parameter can have default value", Current.Line, Current.Position); } Require(Equal); var v = ParseConstExpr(symTable); var s = new ParameterSymbol { Name = idents[0], ParameterModifier = ParameterModifier.Value, Type = (TypeSymbol)tp, Value = v }; symTable.Add(idents[0], s); return(new Parameters { s }); } var p = new Parameters(); foreach (var i in idents) { var s = new ParameterSymbol { Name = i, ParameterModifier = ParameterModifier.Value, Type = (TypeSymbol)tp, }; p.Add(s); symTable.Add(i, s); } return(p); }
private void ParseFunctionDecl(SymTable symTable) { var c = Current; SymTable procSymTable = new SymTable { Parent = symTable }; var h = ParseFunctionHeading(procSymTable); Require(Semicolon); if (symTable.Contains(h.Name)) { throw new ParserException("Duplicate identifier {h.Name}", c.Line, c.Position); } var f = new FunctionSymbol { Name = h.Name, Parameters = h.Parameters, ReturnType = h.ReturnType }; symTable.Add(h.Name, f); var backup = CurrentReturnType; CurrentReturnType = f.ReturnType; var b = ParseBlock(procSymTable); CurrentReturnType = backup; Require(Semicolon); f.Block = b; }
private void ParseProcedureDecl(SymTable symTable) { var c = Current; SymTable procSymTable = new SymTable { Parent = symTable }; var h = ParseProcedureHeading(procSymTable); Require(Semicolon); if (symTable.Contains(h.Name)) { throw new ParserException($"Duplicate identifier {h.Name}", c.Line, c.Position); } var p = new ProcedureSymbol { Name = h.Name, Parameters = h.Parameters }; symTable.Add(h.Name, p); var backup = CurrentReturnType; CurrentReturnType = null; var b = ParseBlock(procSymTable); CurrentReturnType = backup; p.Block = b; Require(Semicolon); }
private void ParseFieldDecl(SymTable parentSymTable, SymTable recSymTable) { var c = Current; Require(Identifier); List <string> idents = new List <string> { c.Value.ToString() }; var t = Current; while (t.SubType == Comma) { Next(); t = Current; Require(Identifier); idents.Add(t.Value.ToString()); } Require(Colon); var tp = ParseType(parentSymTable); foreach (var i in idents) { if (recSymTable.Contains(i)) { throw new ParserException($"Field {i} already declared", c.Line, c.Position); } recSymTable.Add(i, new VarSymbol { Name = i, Type = tp, Value = null }); } }
private void ParseConstantDecl(SymTable symTable) { var c = Current; Next(); if (Current.SubType == Equal) { Next(); var ce = ParseConstExpr(symTable); if (symTable.Contains(c.Value.ToString())) { throw new ParserException($"Duplicate identifier {c.Value}", c.Line, c.Position); } symTable.Add(c.Value.ToString(), new ConstSymbol { Name = c.Value.ToString(), Type = ce.Type, Value = new SimpleConstant { Type = ce.Type, Value = ce.Value } }); return; } if (Current.SubType != Colon) { throw new ParserException($"Expected '=' or ':', got {Current.SubType}.", Current.Line, Current.Position); } Next(); var t = ParseType(symTable); Require(Equal); var tc = ParseTypedConstant(symTable, t); CheckImplicitTypeCompatibility(tc.Type, t); symTable.Add(c.Value.ToString(), new TypedConstSymbol { Name = c.Value.ToString(), Type = t, Value = new SimpleConstant { Type = t, Value = tc } }); }
private void ParseVarDecl(SymTable symTable) { var c = Current; Require(Identifier); var tmp = Current; List <string> idents = new List <string> { c.Value.ToString() }; while (tmp.SubType == Comma) { Next(); tmp = Current; Require(Identifier); idents.Add(tmp.Value.ToString()); tmp = Current; } Require(Colon); var t = ParseType(symTable); if (idents.Count == 1 && Current.SubType == Equal) { Next(); var v = ParseTypedConstant(symTable, t); CheckImplicitTypeCompatibility(v.Type, t); symTable.Add(idents[0], new VarSymbol { Name = idents[0], Type = t, Value = v }); return; } if (Current.SubType == Equal) { throw new ParserException("Only 1 variable can be initialized", Current.Line, Current.Position); } foreach (var i in idents) { symTable.Add(i, new VarSymbol { Name = i, Type = t, Value = null }); } }
private PascalProgram ParseProgram() { var c = Current; string name = ""; if (c.SubType == Tokenizer.TokenSubType.Program) { Next(); var n = Current; Require(Identifier); name = n.Value.ToString(); Require(Semicolon); } SymTable st = new SymTable { { TypeSymbol.IntTypeSymbol.Name, TypeSymbol.IntTypeSymbol }, { TypeSymbol.RealTypeSymbol.Name, TypeSymbol.RealTypeSymbol }, { TypeSymbol.CharTypeSymbol.Name, TypeSymbol.CharTypeSymbol } }; if (st.LookUp(name) != null) { throw new ParserException("Illegal program name", c.Line, c.Position); } ProgramSymbol pn; if (name != "") { pn = new ProgramSymbol { Name = name }; st.Add(name, pn); } else { pn = new ProgramSymbol { Name = "" }; } var b = ParseBlock(st); Require(Dot); return(new PascalProgram { Block = b, Name = pn }); }
private Parameters ParseVarParameter(SymTable symTable) { Require(Var); List <string> idents = new List <string>(); while (Current.SubType == Identifier) { idents.Add(Current.Value.ToString()); Next(); if (Current.SubType != Comma) { break; } Next(); } if (idents.Count == 0) { throw new ParserException("Empty parameter list", Current.Line, Current.Position); } Require(Colon); var t = Current; Require(Identifier); var tp = symTable.LookUp(t.Value.ToString()); if (!(tp is TypeSymbol)) { throw new ParserException("Illegal type declaration", t.Line, t.Position); } var p = new Parameters(); foreach (var i in idents) { var s = new ParameterSymbol { Name = i, ParameterModifier = ParameterModifier.Var, Type = (TypeSymbol)tp }; p.Add(s); symTable.Add(i, s); } return(p); }