コード例 #1
0
        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;
            }
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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;
        }
コード例 #4
0
        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);
        }
コード例 #5
0
        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
                });
            }
        }
コード例 #6
0
        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
                }
            });
        }
コード例 #7
0
        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
                });
            }
        }
コード例 #8
0
        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
            });
        }
コード例 #9
0
        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);
        }