在C#中为BASIC解释器编写Tokenizer类

时间:2009-12-07 10:04:43

标签: c#

为了一点乐趣,我试图用C#编写一个BASIC解释器。以下是我的Tokenizer类(只有几个关键字)。我正在提出任何建议或意见......代码清晰度对我来说比效率更重要。非常感谢。

class Tokenizer
    {

        const string Operators = "+-/*%<>=&|";
        private List<string> Keywords = new List<string>{"LET", "DIM", "PRINT", "REM"};

        private List<string> tokens = new List<string>();
        private List<string> tokenTypes = new List<string>();

        private int tokenIndex;

        // Turn command string into tokens        
        public void Tokenize(string cmdLine)
        {
            string token = "";
            char lastc = ' ';
            bool inString = false;

            tokens.Clear();
            tokenTypes.Clear();

            // Step through line and split into tokens
            foreach (char c in cmdLine)
            {
                if (c == '"') inString = !inString;

                if (!inString)
                {
                    if (IsOperator(lastc)) AddToken(ref token);
                    if (IsWhitespace(c)) AddToken(ref token);
                    if (IsOperator(c)) AddToken(ref token);
                    if (IsNumber(c) && !IsNumber(lastc)) AddToken(ref token);

                    if (!IsWhitespace(c)) token += c;
                }
                else
                    token += c;

                lastc = c;
            }

            // Add last token
            AddToken(ref token);

            tokenIndex = 0;

        }

        public string Token()
        {
            return tokens[tokenIndex];
        }

        public string TokenType()
        {
            return tokenTypes[tokenIndex];
        }

        public void NextToken()
        {            
           tokenIndex++;            
        }

        public bool TokensLeft()
        {
            return tokenIndex < tokens.Count;
        }

        // Add a token to the collection
        private void AddToken(ref string token)
        {
            if (token.Trim() != "")
            {
                // Determine token type
                string tokenType = "Identifier";
                if (IsOperator(token[0])) tokenType = "Operator";
                if (IsNumber(token[0])) tokenType = "Number";
                if (token[0] == '"') tokenType = "String";
                if (Keywords.Contains(token.ToUpper())) tokenType = "Keyword";

                tokens.Add(token);
                tokenTypes.Add(tokenType);
                token = "";
            }
        }

        private bool IsWhitespace(char c)
        {
            return (c.ToString() != c.ToString().Trim());
        }

        private bool IsOperator(char c)
        {
            return Operators.Contains(c);
        }

        private bool IsNumber(char c)
        {
            return Char.IsNumber(c);
        }
    }

1 个答案:

答案 0 :(得分:3)

你通常不想手动编写像这样的解析器代码,如果你要处理超过计算机语言的解析,学习一个好的解析器生成器工具,如Antlr是你的时间的一个很好的投资只是有趣/编码练习。话虽这么说,如果你真的想手动完成这个,你需要考虑一些事情:

  • 使用StringBuilder而不是字符串
  • 只是检查报价是不够的,转发报价呢?
  • 您将如何处理浮点数(所有格式)?
  • 您将如何处理包含数字的标识符?

这些是你会遇到的一些问题,我真的建议学习一个解析器生成器工具,它使这种事情更有趣(更不用说正确和有效)。