Ejemplo n.º 1
0
        /**
         * 어휘 분석이 끝난 계층 트리의 구조를 보여준다.
         *
         * @param units
         * @param level
         */
        public void viewHierarchy(Lextree tree, int level)
        {
            string space = "";

            foreach (int i in Enumerable.Range(0, level))
            {
                space += "      ";
            }

            foreach (int i in Enumerable.Range(0, tree.branch.Count))
            {
                // 새 가지일 때
                if (tree.branch[i].hasBranch)
                {
                    //Sys.print(space + "<begin>\n");

                    viewHierarchy(tree.branch[i], level + 1);
                    //Sys.print(space + "<end>\n");
                }

                // 어휘 데이터일 때
                else
                {
                    if (tree.branch[i].lexData.Count < 1)
                    {
                        continue;
                    }


                    string buffer = "";
                    foreach (int j in Enumerable.Range(0, tree.branch[i].lexData.Count))
                    {
                        Token token = tree.branch[i].lexData[j];
                        buffer += token.value.Trim() + "@" + token.type;
                        if (j != tree.branch[i].lexData.Count - 1)
                        {
                            buffer += ",  ";
                        }
                    }
                    //Sys.print(space + buffer + "\n");
                }
            }
        }
Ejemplo n.º 2
0
        public Lextree analyze(string code)
        {
            processingLine = 1;

            // 어휘 트리를 생성한다.
            Lextree tree = new Lextree(true, processingLine);

            // 문자열 처리 상태 변수를 초기화한다.
            bool   isString = false;
            string buffer   = "";

            int i = -1;

            while (++i < code.Length)
            {
                char _char = code[i];

                // 줄바꿈 문자일 경우 줄 번호를 하나 증가시킨다.
                if (_char == '\n')
                {
                    processingLine++;
                }

                // 문자열의 시작과 종결 부분을 감지하여 상태를 업데이트한다.
                if (_char == '\"')
                {
                    isString = !isString;
                    buffer  += _char;
                    continue;
                }

                // 모든 문자열 정보는 버퍼에 저장한다.
                if (isString)
                {
                    buffer += _char;
                    continue;
                }

                // 주석을 제거한다.
                if (_char == '/' && i + 1 < code.Length)
                {
                    int j = 2;

                    // 단일 행 주석일 경우
                    if (code[i + 1] == '/')
                    {
                        // 문장의 끝(줄바꿈 문자)를 만날 때까지 넘긴다.
                        while (i + j <= code.Length)
                        {
                            if (code[i + (j++)] == '\n')
                            {
                                break;
                            }
                        }
                        i += j - 1;
                        processingLine++;
                        continue;
                    }

                    // 여러 행 주석일 경우
                    else if (code[i + 1] == '*')
                    {
                        // 종결 문자열 시퀸스('*/')를 만날 때까지 넘긴다.
                        while (i + j < code.Length)
                        {
                            if (code[i + j] == '\n')
                            {
                                processingLine++;
                            }

                            if (code[i + (j++)] == '*')
                            {
                                if (code[i + (j++)] == '/')
                                {
                                    break;
                                }
                            }
                        }
                        i += j - 1;
                        continue;
                    }
                }

                // 세미콜론을 찾으면 진행 상황을 스택에 저장한다.
                if (_char == ';')
                {
                    // 진행 상황을 스택에 저장한다.
                    if (buffer.Length > 0)
                    {
                        Lextree lextree = new Lextree(false, processingLine);
                        lextree.lexData = tokenize(buffer);
                        tree.branch.Add(lextree);
                    }

                    // 버퍼를 초기화한다.
                    buffer = "";
                }

                // 중괄호 열기 문자('{')를 찾으면 괄호로 묶인 그룹을 재귀적으로 처리하여 저장한다.
                else if (_char == '{')
                {
                    // 중괄호 앞의 데이터를 저장한다.
                    if (buffer.Length > 0)
                    {
                        Lextree lextree = new Lextree(false, processingLine);
                        lextree.lexData = tokenize(buffer);
                        tree.branch.Add(lextree);
                    }

                    // 괄호의 끝을 찾는다.
                    int j     = 1;
                    int depth = 0;

                    while (i + j <= code.Length)
                    {
                        char __char = code[i + (j++)];
                        if (__char == '{')
                        {
                            depth++;
                        }
                        else if (__char == '}')
                        {
                            depth--;
                        }
                        else if (__char == '\n')
                        {
                            processingLine++;
                        }
                        if (depth < 0)
                        {
                            break;
                        }
                    }

                    // 괄호의 전체 내용에 대해 구문 분석을 수행한 후, 유닛에 추가한다. (시작, 끝 괄호 제외)
                    Lextree block = analyze(code.Substring(i + 1, i + j - 1 - (i + 1)));
                    tree.branch.Add(block);

                    // 다음 과정을 준비한다.
                    buffer = "";
                    i     += j - 1;
                }

                // 처리하지 않는 문자일 경우 버퍼에 쓴다.
                else
                {
                    buffer += _char;
                }
            }

            // 맨 뒤의 데이터도 쓴다.
            if (buffer.Length > 0)
            {
                Lextree lextree = new Lextree(false, processingLine);
                lextree.lexData = tokenize(buffer);
                tree.branch.Add(lextree);
            }

            // 분석 결과를 리턴한다.
            return(tree);
        }