﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace CommandParser
{
    public class Parser
    {
        public static void Parse(List<Token> tokens, out string str_namespace, out string str_func, out List<object> args)
        {
            bool can_TAG_DOT = false;
            bool can_TAG_COMMA = false;
            bool can_TAG_BRACKET_LEFT = false;
            bool can_TAG_BRACKET_RIGHT = false;

            bool can_STRING = false;
            bool can_BOOL = false;
            bool can_INT = false;
            bool can_FLOAT = false;
            bool can_WORD = true;

            bool readParams = false;

            List<string> callerList = new List<string>();
            str_namespace = "";
            str_func = "";
            args = new List<object>();

            foreach (Token tk in tokens)
            {
                #region 判断是否符合规则

                if (tk is TKTag)
                {
                    TKTag tk0 = tk as TKTag;
                    if (!can_TAG_DOT && tk0.value == Lexer.DOT ||
                        !can_TAG_COMMA && tk0.value == Lexer.COMMA ||
                        !can_TAG_BRACKET_LEFT && tk0.value == Lexer.BRACKET_LEFT ||
                        !can_TAG_BRACKET_RIGHT && tk0.value == Lexer.BRACKET_RIGHT)
                    {
                        Console.WriteLine(tk0.type + ": " + tk0.value + "," + can_TAG_DOT);
                        throw new ArgumentException("Parser error, undefined semantics.");
                    }
                    if (tk0.value == Lexer.BRACKET_LEFT)
                        readParams = true;
                }
                else
                {
                    if (!can_STRING && tk is TKString || !can_BOOL && tk is TKBool ||
                        !can_INT && tk is TKInt || !can_FLOAT && tk is TKFloat ||
                        !can_WORD && tk is TKWord)
                    {
                        throw new ArgumentException("Parser error, undefined semantics.");
                    }
                }

                #endregion

                #region 传入StringBuilder

                if (readParams)
                {
                    if (!(tk is TKTag))
                    {
                        args.Add(tk.GetValue());
                    }
                }
                else
                {
                    callerList.Add(tk.GetValue().ToString());
                }

                #endregion

                #region 重置规则

                can_TAG_DOT = false;
                can_TAG_COMMA = false;
                can_TAG_BRACKET_LEFT = false;
                can_TAG_BRACKET_RIGHT = false;
                can_STRING = false;
                can_BOOL = false;
                can_INT = false;
                can_FLOAT = false;
                can_WORD = false;

                #endregion

                #region 设置规则

                if (tk is TKTag)
                {
                    if (readParams)
                    {
                        // 正在读取 参数
                        can_TAG_COMMA = can_TAG_BRACKET_RIGHT = true;
                        can_STRING = can_BOOL = can_INT = can_FLOAT = true;
                    }
                    else
                    {
                        // 正在读取 调用者
                        can_WORD = true;
                    }
                }
                else if (tk is TKWord)
                {
                    can_TAG_DOT = can_TAG_BRACKET_LEFT = true;
                }
                else if (tk is TKString || tk is TKBool || tk is TKInt || tk is TKFloat)
                {
                    can_TAG_COMMA = can_TAG_BRACKET_RIGHT = true;
                }

                #endregion
            }

            if(callerList.Count > 2)
            {
            	StringBuilder builder = new StringBuilder();
            	for(int i = 0; i < callerList.Count - 2; i++)
            		builder.Append(callerList[i]);

            	str_namespace = builder.ToString();
            	str_func = callerList[callerList.Count - 1];
            }
            else
                throw new ArgumentException("Parser error, base class not found.");

        }
    }
}
