Пример #1
0
 /// <summary> 添加一个词法单元信息到列表 | Add a token to list </summary>
 private static void AddToken(List <LBToken> list, LBTag tag, int index, int length, int row, int column)
 {
     if (length > 0)
     {
         list.Add(new LBToken(tag, index, length, row, column));
     }
 }
Пример #2
0
 public LBToken(LBTag tag, int index, int length, int row, int column)
 {
     this.tag    = tag;
     this.index  = index;
     this.length = length;
     this.row    = row;
     this.column = column;
 }
Пример #3
0
        /// <summary> 词法分析(拆分成词法单元) | Lexical analyze(split and get lexical element) </summary>
        public static List <LBToken> Analyze(string code)
        {
            // 检查参数
            if (string.IsNullOrEmpty(code))
            {
                throw new System.ArgumentNullException("code", "Code can not be null or empty");
            }

            List <LBToken> tokens = new List <LBToken>(16);

            // 当前词法单元信息 | Current lexical element info
            MatchState matchState = MatchState.Normal;
            int        row        = 1;
            int        column     = 0;

            // 上一个词法单元信息 | Last lexical element info
            char  lastChar   = '\x0'; // 上一个字符(默认空字符NUL) | Last character(default NUL)
            LBTag lastTag    = LBTag.None;
            int   lastIndex  = 0;
            int   lastLength = 0;
            int   lastRow    = 1;
            int   lastColumn = 0;
            bool  needClear  = false;

            // 扫描所有字符 | Scan all characters
            int total = code.Length;

            for (int index = 0; index < total; index++)
            {
                char c = code[index];

                // 如果注释开始 忽略除换行符和注释结束符以外的所有字符 | If Comments start Ignore all characters except newline and comments end characters
                if (matchState == MatchState.SingleLineComments)
                {
                    // 查找单行注释结束 '\n' | Find single-line comments end '\n'
                    if (c == '\n')
                    {
                        row       += 1;
                        column     = 0;
                        needClear  = true;
                        matchState = MatchState.Normal;
                    }
                }
                else if (matchState == MatchState.MultiLineComments)
                {
                    if (c == '\n')
                    {
                        // 换行符 | New line character
                        row      += 1;
                        column    = 0;
                        needClear = true;
                    }
                    else if (c == '/' && lastChar == '*')
                    {
                        // 查找多行注释结束 "*/" | Find multi-line comments end "*/"
                        needClear  = true;
                        matchState = MatchState.Normal;
                    }
                }
                else if (c == ' ' || c == '\t')
                {
                    // 分隔符 | Separator characters
                    if (lastLength > 0)
                    {
                        needClear = true;
                        tokens.Add(new LBToken(lastTag, lastIndex, lastLength, lastRow, lastColumn));
                    }
                    else
                    {
                        needClear = false;
                    }
                }
                else if (c == '\r')
                {
                    // 忽略符 | Ignore character
                    continue;
                }
                else if (c == '\n')
                {
                    // 拆分符 | Split characters
                    row      += 1;
                    column    = 0;
                    needClear = true;
                    AddToken(tokens, lastTag, lastIndex, lastLength, lastRow, lastColumn);
                }
                else if (c == ';')
                {
                    AddToken(tokens, lastTag, lastIndex, lastLength, lastRow, lastColumn);
                    tokens.Add(new LBToken(LBTag.Semicolon, index, 1, row, column));
                    needClear = true;
                }
                else if (c == ',')
                {
                    AddToken(tokens, lastTag, lastIndex, lastLength, lastRow, lastColumn);
                    tokens.Add(new LBToken(LBTag.Comma, index, 1, row, column));
                    needClear = true;
                }
                else if (c == '[')
                {
                    AddToken(tokens, lastTag, lastIndex, lastLength, lastRow, lastColumn);
                    tokens.Add(new LBToken(LBTag.LSquareBracket, index, 1, row, column));
                    needClear = true;
                }
                else if (c == ']')
                {
                    AddToken(tokens, lastTag, lastIndex, lastLength, lastRow, lastColumn);
                    tokens.Add(new LBToken(LBTag.RSquareBracket, index, 1, row, column));
                    needClear = true;
                }
                else if (c == '<')
                {
                    AddToken(tokens, lastTag, lastIndex, lastLength, lastRow, lastColumn);
                    tokens.Add(new LBToken(LBTag.LAngleBracket, index, 1, row, column));
                    needClear = true;
                }
                else if (c == '>')
                {
                    AddToken(tokens, lastTag, lastIndex, lastLength, lastRow, lastColumn);
                    tokens.Add(new LBToken(LBTag.RAngleBracket, index, 1, row, column));
                    needClear = true;
                }
                else if (c == '{')
                {
                    AddToken(tokens, lastTag, lastIndex, lastLength, lastRow, lastColumn);
                    tokens.Add(new LBToken(LBTag.LCurlyBrace, index, 1, row, column));
                    needClear = true;
                }
                else if (c == '}')
                {
                    AddToken(tokens, lastTag, lastIndex, lastLength, lastRow, lastColumn);
                    tokens.Add(new LBToken(LBTag.RCurlyBrace, index, 1, row, column));
                    needClear = true;
                }
                else
                {
                    // 其他符号 | Other characters
                    if (lastLength == 0)
                    {
                        // 新的单词开始 | New word start
                        lastTag    = LBTag.Word;
                        lastIndex  = index;
                        lastLength = 1;
                    }
                    else
                    {
                        // 添加新字符
                        if (matchState == MatchState.Normal)
                        {
                            if (lastChar == '/')
                            {
                                // 判断注释是否开始 | Check if comments start
                                if (c == '/')
                                {
                                    // 单行注释 | Single-line comments start
                                    matchState = MatchState.SingleLineComments;
                                }
                                else if (c == '*')
                                {
                                    // 多行注释开始 | Multi-line comments start
                                    matchState = MatchState.MultiLineComments;
                                }
                                else
                                {
                                    // 非注释 添加字符 | Not comments. Add character
                                    lastLength += 1;
                                }
                            }
                            else
                            {
                                // 非注释 添加字符 | Not comments. Add character
                                lastLength += 1;
                            }
                        }
                    }
                }

                // 已添加了词法单元信息 重置临时数据 | Reset temp data after add token
                if (needClear)
                {
                    needClear  = false;
                    lastChar   = '\x0';
                    lastTag    = LBTag.None;
                    lastIndex  = index;
                    lastLength = 0;
                    lastRow    = row;
                    lastColumn = column;
                }
                column  += 1;
                lastChar = c;
            }
            AddToken(tokens, lastTag, lastIndex, lastLength, lastRow, lastColumn);
            return(tokens);
        }
Пример #4
0
        /// <summary> 语法解析 | Syntax parse  </summary>
        public static LBReport Analyze(string code, List <LBToken> tokens)
        {
            // 检查参数
            if (string.IsNullOrEmpty(code))
            {
                throw new System.ArgumentNullException("code", "Code can not be null or empty");
            }
            if (tokens == null || tokens.Count == 0)
            {
                throw new System.ArgumentNullException("tokens", "Tokens can not be null or empty");
            }

            string error = "";
            // 筛选有效单词 | Get valid worlds
            List <LBToken> validTokens = new List <LBToken>(7);
            int            total       = tokens.Count;

            for (int i = 0; i < total; i++)
            {
                LBToken token = tokens[i];
                if (token.tag == LBTag.Word)
                {
                    // 检查单词有效性 | Valid word
                    if (IsDigit(code[token.index]))
                    {
                        // 第一个字符不能为数字 | The first character cannot be a number
                        string err = "The first character of an identifier cannot be a number ";
                        err  += '\'' + code[token.index].ToString() + '\'';
                        error = error + GetErrorPrefix(code, token) + err + '\n';
                        continue;
                    }
                    else if (IsAccessModifier(code, token))
                    {
                        // 忽略访问修饰符 | Ignore access modifier
                        continue;
                    }
                }

                // 添加有效单词 | Add valid word
                validTokens.Add(token);
            }
            if (error != "")
            {
                return(new LBReport(false, null, error));
            }

            // 检查是否是结构体格式 | Valid type format
            if (validTokens.Count < 7)
            {
                error += "Parse struct error: Not enough words";
                return(new LBReport(false, null, error));
            }

            bool isClass  = IsMatch(code, validTokens[0], "class");
            bool isStruct = IsMatch(code, validTokens[0], "struct");

            if (!isClass && !isStruct)
            {
                LBToken token = validTokens[0];
                string  err   = "Unexpected word \"" + GetString(code, token) + "\" expecting \"class\" or \"struct\" ";
                error = error + GetErrorPrefix(code, token) + err + '\n';
            }
            if (!IsMatch(code, validTokens[2], "{"))
            {
                LBToken token = validTokens[2];
                string  err   = "Unexpected word \"" + GetString(code, token) + "\" expecting '{'";
                error = error + GetErrorPrefix(code, token) + err + '\n';
            }
            if (!IsMatch(code, validTokens[validTokens.Count - 1], "}"))
            {
                LBToken token = validTokens[validTokens.Count - 1];
                string  err   = "Unexpected word \"" + GetString(code, token) + "\" expecting '}'";
                error = error + GetErrorPrefix(code, token) + err + '\n';
            }
            if (error != "")
            {
                return(new LBReport(false, null, error));
            }

            // 解析结构体字段 | Parse fields
            int           count             = validTokens.Count - 1;
            List <LBType> fields            = new List <LBType>();
            LBType        field             = new LBType();
            bool          hasType           = false;
            bool          hasName           = false;
            bool          hasLSquareBracket = false;
            bool          hasRSquareBracket = false;

            for (int i = 3; i < count; i++)
            {
                LBToken token = validTokens[i];
                LBTag   tag   = token.tag;
                if (!hasType)
                {
                    // 匹配字段类型 | Match field type
                    if (tag == LBTag.Word)
                    {
                        hasType = true;
                        field.InitTypeName(GetString(code, token), field.Name);
                    }
                    else
                    {
                        string err = "Unexpected word \"" + GetString(code, token) + "\" expecting [FieldType]";
                        error = error + GetErrorPrefix(code, token) + err + '\n';
                    }
                }
                else if (!hasName)
                {
                    // 匹配字段名称 | Match field name
                    if (tag == LBTag.Word)
                    {
                        hasName = true;
                        field.InitTypeName(field.Type, GetString(code, token));
                    }
                    else
                    {
                        // 匹配数组的"[]" | Match array "[]"
                        if (!hasLSquareBracket && tag == LBTag.LSquareBracket)
                        {
                            hasLSquareBracket = true;
                        }
                        else if (hasLSquareBracket && !hasRSquareBracket)
                        {
                            if (tag == LBTag.RSquareBracket)
                            {
                                // 匹配到数组 "[]" | Match to array "[]"
                                hasRSquareBracket = true;
                                LBType elementType = new LBType(field.Type, null);
                                field.InitTypeName(field.Type + "[]", field.Name);
                                field.InitArray(elementType);
                            }
                            else
                            {
                                string err = "Unexpected word \"" + GetString(code, token) + "\" expecting ']'";
                                error = error + GetErrorPrefix(code, token) + err + '\n';
                            }
                        }
                        else
                        {
                            string err = "Unexpected word \"" + GetString(code, token) + "\" expecting [FieldName]";
                            error = error + GetErrorPrefix(code, token) + err + '\n';
                        }
                    }
                }
                else
                {
                    // 匹配字段结束 | Match end
                    if (tag == LBTag.Semicolon)
                    {
                        fields.Add(field);
                    }
                    else
                    {
                        string err = "Expecting \";\"";
                        error = error + GetErrorPrefix(code, validTokens[i - 1]) + err + '\n';
                        if (i > 3)
                        {
                            i -= 1;
                        }
                    }

                    // 重置临时数据 | Reset temp data
                    field             = new LBType();
                    hasType           = false;
                    hasName           = false;
                    hasLSquareBracket = false;
                    hasRSquareBracket = false;
                }
            }

            // 最末尾 | At the end
            if (hasType)
            {
                LBToken token = validTokens[count - 1];
                if (!hasName)
                {
                    string err = "Expecting [FieldName]";
                    error = error + GetErrorPrefix(code, token) + err + '\n';
                }
                else
                {
                    string err = "Expecting \";\"";
                    error = error + GetErrorPrefix(code, validTokens[count - 2]) + err + '\n';
                }
            }

            // 检查字段数量 | Check fields count
            if (fields.Count == 0)
            {
                error = error + "Valid field count is 0";
            }
            if (error != "")
            {
                return(new LBReport(false, null, error));
            }

            // 生成主体类型 | Generate main type
            LBType customType = new LBType(GetString(code, validTokens[0]), GetString(code, validTokens[1]));

            customType.InitCustomType(isClass, isStruct, fields);
            return(new LBReport(true, customType, null));
        }