Ejemplo n.º 1
0
        protected string ParseDomainName()
        {
            StringBuilder builder = new StringBuilder();

            do
            {
                if (token.Type == TokenType.Identifier)
                {
                    WordToken wt = token as WordToken;
                    builder.Append(wt.Word);
                }
                else if (token.Type == tokenAt)
                {
                    builder.Append("@");
                }
                else if (token.Type == tokenDot)
                {
                    builder.Append(".");
                }

                GetToken(false);
            }while (token.Type != TokenType.Whitespace && token.Type != TokenType.EndOfFile && token.Type != TokenType.Numeric && token.Type != tokenControl && !token.IsInList(tokensQueryClass) && !token.IsInList(tokensQueryType));

            // skip the rest of the whitespace to have the next token ready
            GetToken();

            return(builder.ToString());
        }
Ejemplo n.º 2
0
        // TODO: maintain a list of token types provided by parser so that scanner can remain unbiased

        // TODO: maintain a list of special token types

        public Token GetToken()
        {
            SkipWhitespace();

            if (currType == CharType.Alpha)
            {
                WordToken token = WordToken.GetToken(this);
                // TODO: check for reserved words
                return(token);
            }
            else if (currType == CharType.Numeric)
            {
                return(NumberToken.GetToken(this));
            }
            else if (currType == CharType.Quote)
            {
                return(StringToken.GetToken(this));
            }
            else if (currType == CharType.EOF)
            {
                return(new EndOfFileToken());
            }
            else if (currType == CharType.Special)
            {
                SpecialToken token = SpecialToken.GetToken(this);
                // TODO: check for special token types
                return(token);
            }

            return(null);
        }
Ejemplo n.º 3
0
        protected override void GetToken()
        {
            base.GetToken();

            // tokenise special tokens according to this language
            // multi-character special tokens can also be added by checking scanner.curr for continuation
            if (token.Type == TokenType.Special)
            {
                SpecialToken st = token as SpecialToken;
                switch (st.Token)
                {
                case '=':
                    token.Type = tokenEquals;
                    break;

                case ';':
                    token.Type = tokenSemicolon;
                    break;

                case '+':
                    token.Type = tokenPlus;
                    break;

                case '-':
                    token.Type = tokenMinus;
                    break;

                case '/':
                    token.Type = tokenDivide;
                    break;

                case '*':
                    token.Type = tokenMultiply;
                    break;

                case '(':
                    token.Type = tokenOpenParentheses;
                    break;

                case ')':
                    token.Type = tokenCloseParentheses;
                    break;
                }
            }
            else if (token.Type == TokenType.Identifier)
            {
                // rule out identifiers that are actually reserved words. could be const values like "pi" or logic keywords like "if/then/else/while etc."
                WordToken wt = token as WordToken;
                switch (wt.Word)
                {
                case "pi":
                    token.Type = tokenPi;
                    break;
                }
            }
        }
Ejemplo n.º 4
0
        // TODO: maintain a list of token types provided by parser so that scanner can remain unbiased

        // TODO: maintain a list of special token types

        public Token GetToken(bool skipWhitespace = true)
        {
            if (skipWhitespace)
            {
                SkipWhitespace();
            }

            if (currType == CharType.Whitespace)
            {
                return(new Token()
                {
                    Type = TokenType.Whitespace
                });
            }
            else if (currType == CharType.Alpha)
            {
                WordToken token = WordToken.GetToken(this);
                // TODO: check for reserved words
                return(token);
            }
            else if (currType == CharType.Numeric)
            {
                // TODO: need a scanner options class that lets me specify things like
                // skipping whitespace, treating numbers etc.
                // because here an IP address will be treated as a decimal number
                // 192.0[.2.1]
                return(NumberToken.GetToken(this));
            }
            else if (currType == CharType.Quote)
            {
                return(StringToken.GetToken(this));
            }
            else if (currType == CharType.EOF)
            {
                return(new EndOfFileToken());
            }
            else if (currType == CharType.Special)
            {
                SpecialToken token = SpecialToken.GetToken(this);
                // TODO: check for special token types
                return(token);
            }

            return(null);
        }
Ejemplo n.º 5
0
        protected override void ParseFactor()
        {
            if (token.Type == TokenType.Identifier)
            {
                WordToken wt   = token as WordToken;
                var       node = SearchAll(wt.Word);
                if (node == null)
                {
                    throw new InvalidOperationException("Unknown identifier");
                }
                else
                {
                    runtimeStack.Push(node.Value);
                }

                GetToken();
            }
            else if (token.Type == tokenPi)
            {
                runtimeStack.Push(Math.PI);
                GetToken();
            }
            else if (token.Type == TokenType.Numeric)
            {
                NumberToken nt = token as NumberToken;
                runtimeStack.Push(nt.Value);
                GetToken();
            }
            else if (token.Type == tokenOpenParentheses)
            {
                GetToken();

                ParseExpression();

                if (token.Type == tokenCloseParentheses)
                {
                    GetToken();
                }
                else
                {
                    throw new InvalidOperationException("No closing parentheses");
                }
            }
        }
Ejemplo n.º 6
0
        public Token Get()
        {
            int tokenCode = -1;

            do
            {
                tokenCode = code[index++];
                if (tokenCode == TokenType.LineMarker)
                {
                    // TODO: replicate the global currentLineNumber from book
                    int lineNumber = code[index++];
                }
            }while (tokenCode == TokenType.LineMarker);

            if (tokenCode == TokenType.Numeric)
            {
                var token = new NumberToken();
                var node  = GetSymbolTableNode();
                token.Value = node.Value;
                return(token);
            }

            if (tokenCode == TokenType.String)
            {
                var token = new StringToken();
                var node  = GetSymbolTableNode();
                token.Value = node.Symbol;
                return(token);
            }

            if (tokenCode == TokenType.Identifier)
            {
                var token = new WordToken();
                var node  = GetSymbolTableNode();
                token.Word = node.Symbol;
                return(token);
            }

            var defaultToken = new WordToken();

            defaultToken.Word = "";
            return(defaultToken);
        }
Ejemplo n.º 7
0
        public static WordToken GetToken(Scanner scanner)
        {
            WordToken t = new WordToken();

            t.sc = scanner.col;
            t.sr = scanner.row;
            StringBuilder sb = new StringBuilder();

            while (scanner.currType == CharType.Alpha || scanner.currType == CharType.Numeric)
            {
                sb.Append(scanner.curr);
                scanner.Next();
            }
            t.Word = sb.ToString();
            t.ec   = scanner.col;
            t.er   = scanner.row;

            t.Type = TokenType.Identifier;

            return(t);
        }
Ejemplo n.º 8
0
        protected override void ParseAssignment()
        {
            WordToken identifier = token as WordToken;
            var       node       = SearchAll(identifier.Word);

            if (node == null)
            {
                node = EnterLocal(identifier.Word);
            }

            GetToken();

            if (token.Type == tokenEquals)
            {
                GetToken();

                ParseExpression();

                node.Value = runtimeStack.Pop();
            }
        }
Ejemplo n.º 9
0
        protected override void GetToken(bool skipWhitespace = true)
        {
            base.GetToken(skipWhitespace);

            if (token.Type == TokenType.Special)
            {
                SpecialToken st = token as SpecialToken;
                if (st.Token == ';')
                {
                    // we don't care about comments, keep scanning and return a real token
                    token.Type = tokenSemicolon;
                    do
                    {
                        scanner.Next();
                    }while (scanner.curr != '\n');
                    scanner.Next();
                    GetToken(skipWhitespace);
                }
                else if (st.Token == '$')
                {
                    token.Type = tokenControl;
                }
                else if (st.Token == '(')
                {
                    // TODO: I think don't ignore these, but i need to know when they will come
                    // so far SOA and WKS records, but if they could come anywhere then
                    // i need to cater for that
                    // WKS is particularly problematic because it isn't fixed length fields

                    //token.Type = tokenOpenParentheses;
                    // i think just ignore parentheses
                    GetToken(skipWhitespace);
                }
                else if (st.Token == ')')
                {
                    // token.Type = tokenCloseParentheses;
                    GetToken(skipWhitespace);
                }
                else if (st.Token == '.')
                {
                    token.Type = tokenDot;
                }
                else if (st.Token == ':')
                {
                    token.Type = tokenColon;
                }
                else if (st.Token == '@')
                {
                    token.Type = tokenAt;
                }
            }
            else if (token.Type == TokenType.Identifier)
            {
                WordToken wt = token as WordToken;
                if (wt.Word == "INCLUDE")
                {
                    token.Type = tokenInclude;
                }
                else if (wt.Word == "ORIGIN")
                {
                    token.Type = tokenOrigin;
                }
                else if (wt.Word == "TTL")
                {
                    token.Type = tokenTTL;
                }
                else if (wt.Word == "IN")
                {
                    token.Type = tokenInternet;
                }
                else if (wt.Word == "CS")
                {
                    token.Type = tokenCSNET;
                }
                else if (wt.Word == "CH")
                {
                    token.Type = tokenChaos;
                }
                else if (wt.Word == "HS")
                {
                    token.Type = tokenHesiod;
                }
                else if (wt.Word == "AFXR")
                {
                    token.Type = tokenTransfer;
                }
                else if (wt.Word == "MAILB")
                {
                    token.Type = tokenMailbox;
                }
                else if (wt.Word == "MAILA")
                {
                    token.Type = tokenMailAgent;
                }
                else if (wt.Word == "A")
                {
                    token.Type = tokenHostAddress;
                }
                else if (wt.Word == "AAAA")
                {
                    token.Type = tokenHostIPv6Address;
                }
                else if (wt.Word == "NS")
                {
                    token.Type = tokenNameServer;
                }
                else if (wt.Word == "MD")
                {
                    token.Type = tokenMailDestination;
                }
                else if (wt.Word == "MF")
                {
                    token.Type = tokenMailForwarder;
                }
                else if (wt.Word == "CNAME")
                {
                    token.Type = tokenCanonicalName;
                }
                else if (wt.Word == "SOA")
                {
                    token.Type = tokenAuthority;
                }
                else if (wt.Word == "WKS")
                {
                    token.Type = tokenWellKnownService;
                }
                else if (wt.Word == "PTR")
                {
                    token.Type = tokenPointer;
                }
                else if (wt.Word == "HINFO")
                {
                    token.Type = tokenHostInfo;
                }
                else if (wt.Word == "MINFO")
                {
                    token.Type = tokenMailboxInfo;
                }
                else if (wt.Word == "MX")
                {
                    token.Type = tokenMailExchange;
                }
                else if (wt.Word == "TXT")
                {
                    token.Type = tokenText;
                }
            }
        }
Ejemplo n.º 10
0
        protected void ParseResourceRecord()
        {
            bool haveType = false;

            MasterFileEntry entry = new MasterFileEntry();

            while (haveType == false && token.Type != TokenType.EndOfFile)
            {
                if (token.Type == TokenType.Numeric)
                {
                    // most likely a <rr> beginning with TTL
                    //     [<TTL>] [<class>] <type> <RDATA>
                    NumberToken nt = token as NumberToken;
                    entry.TTL = (int)nt.Value;

                    GetToken();
                }
                else if (token.IsInList(tokensQueryClass))
                {
                    // most likely a <rr> beginning with class
                    //     [<class>] [<TTL>] <type> <RDATA>
                    WordToken wt = token as WordToken;
                    entry.Class = wt.Word;

                    GetToken();
                }
                else if (token.IsInList(tokensQueryType))
                {
                    haveType = true;

                    WordToken wt = token as WordToken;
                    entry.Type = wt.Word;

                    // prepare to parse the data
                    if (token.Type == tokenCanonicalName)
                    {
                        // name string - probably fqdn
                        GetToken();

                        entry.Data = ParseDomainName();
                    }
                    else if (token.Type == tokenHostInfo)
                    {
                        // CPU string
                        GetToken();

                        // OS string
                        GetToken();

                        GetToken();
                    }
                    else if (token.Type == tokenMailExchange)
                    {
                        GetToken();

                        NumberToken nt = token as NumberToken;
                        entry.Priority = (int)nt.Value;

                        GetToken();

                        entry.Data = ParseDomainName();
                    }
                    else if (token.Type == tokenNameServer)
                    {
                        GetToken();
                        entry.Data = ParseDomainName();
                    }
                    else if (token.Type == tokenPointer)
                    {
                        GetToken();
                        entry.Data = ParseDomainName();
                    }
                    else if (token.Type == tokenAuthority)
                    {
                        // name server
                        GetToken();
                        // TODO: if token is open parentheses then loop until close parentheses (and stop scanner from swallowing parentheses)
                        entry.NameServer = ParseDomainName();

                        // mailbox of responsible person
                        entry.Responsible = ParseDomainName();

                        // serial number
                        NumberToken nt = token as NumberToken;
                        entry.SerialNumber = (int)nt.Value;

                        // refresh interval
                        GetToken();
                        nt = token as NumberToken;
                        entry.RefreshInterval = (int)nt.Value;

                        // retry interval
                        GetToken();
                        nt = token as NumberToken;
                        entry.RetryInterval = (int)nt.Value;

                        // expiry timeout
                        GetToken();
                        nt = token as NumberToken;
                        entry.ExpiryTimeout = (int)nt.Value;

                        // minimum ttl
                        GetToken();
                        nt = token as NumberToken;
                        entry.MinimumTTL = (int)nt.Value;

                        GetToken();
                    }
                    else if (token.Type == tokenText)
                    {
                        GetToken();

                        // TODO: this is wrong and probably needs additional parsing
                        entry.Data = ((WordToken)token).Word;

                        GetToken();
                    }
                    else if (token.Type == tokenHostAddress)
                    {
                        GetToken();
                        entry.Data = ParseIPv4Address();
                    }
                    else if (token.Type == tokenHostIPv6Address)
                    {
                        GetToken();
                        entry.Data = ParseIPv6Address();
                    }
                    else if (token.Type == tokenWellKnownService)
                    {
                        // address
                        GetToken();

                        string address = ParseIPv4Address();

                        string protocol = ((WordToken)token).Word;

                        // TODO: open parentheses, loop until close
                    }
                }
                else
                {
                    // most likely a <rr> beginning with <owner>
                    //     <domain-name> [<class>] [<TTL>] <type> <RDATA>
                    entry.Owner = ParseDomainName();
                    if (entry.Owner != "@")
                    {
                        // set default owner in case we reach another record that doesn't have an owner
                        // see section 5.1
                        owner = entry.Owner;
                    }
                }
            }

            if (entry.Owner == null)
            {
                entry.Owner = owner;
            }

            if (entry.Owner == "@")
            {
                entry.Owner = origin;
            }
            else if (entry.Owner.EndsWith(".") == false)
            {
                entry.Owner += "." + origin;
            }

            // add to the running list of entries found
            Entries.Add(entry);

            Console.WriteLine($"Parsed resource record: {entry.Owner}\t{entry.Type}\t{entry.Class}\t{entry.Data}");
        }