Exemple #1
0
        private static DelimiterList Do(int indent, string original, string[] strs, int iStart, ValueDelimiter thisDelim,
			IParseLineDelimiters delims, ILineRequestor requestor, out int iEnd)
        {
            List<DelimiterNode> nodes = new List<DelimiterNode>();

            DelimiterType type = thisDelim.DelimiterType;
            if (type == DelimiterType.AsComment)
            {	// ignore everything up to the end delimiter
                DelimiterList result = null;
                if (ParseComment(strs, iStart, thisDelim, out iEnd, out result))
                    return result;
            }
            else if (type == DelimiterType.AsString)
            {	// simply search for end and stuff everything in the middle into a single token
                DelimiterList result = null;
                if (ParseString(indent, strs, iStart, thisDelim, nodes, out iEnd, out result))
                    return result;
            }
            else // Value, Array && Raw
            {	// handle as individual tokens and nested lists
                DelimiterList result = null;
                if (ParseMisc(indent, original, strs, iStart, thisDelim, delims, requestor, nodes, out iEnd, out result))
                    return result;
            }

            // didn't find closing delimiter, TODO request the next line
            if (thisDelim != ValueDelimiter.Line && thisDelim.End != "")
                throw new Loki3Exception().AddMissingEndDelimiter(thisDelim);

            iEnd = strs.Length;
            string trimmed = original.TrimStart(' ', '\t');
            return new DelimiterList(thisDelim, nodes, indent, "", trimmed, null);
        }
Exemple #2
0
 /// <summary>
 /// Creates delimiter list from string,
 /// can request lines if missing closing delimiter
 /// </summary>
 /// <param name="str">line to parse</param>
 /// <param name="requestor">used to ask for additional lines if needed, may be null</param>
 /// <param name="delims">used to ask questions about delimiters</param>
 internal static DelimiterList Do(string str, IParseLineDelimiters delims, ILineRequestor requestor)
 {
     string[] strs = ParseChars.Do(str, delims);
     int indent = Utility.CountIndent(str);
     int end;
     return Do(indent, str, strs, 0, ValueDelimiter.Line, delims, requestor, out end);
 }
Exemple #3
0
            /// <summary>If we haven't already parsed our lines, do so now</summary>
            private void EnsureParsed(IParseLineDelimiters delims)
            {
                if (m_rawLines == null)
                    return;
                m_parsedLines = new List<DelimiterList>(m_rawLines.Count);
                foreach (Value v in m_rawLines)
                {
                    DelimiterList line = null;
                    if (v is ValueString)
                        line = ParseLine.Do(v.AsString, delims);
                    else if (v is ValueRaw)
                        line = (v as ValueRaw).GetValue();

                    if (line != null)
                        m_parsedLines.Add(line);
                }
                m_rawLines = null;
            }
Exemple #4
0
        internal static string[] Do(string s, IParseLineDelimiters delims)
        {
            List<string> list = new List<string>();
            StringBuilder current = new StringBuilder();
            bool atStart = true;
            bool inWord = false;
            bool inString = false;
            char endString = ' ';
            int maxDelimLen = 0;

            // find single char string delims
            //!! fetch from delims
            List<string> quotes = new List<string>();
            Dictionary<string, ValueDelimiter> stringDelims = (delims == null ? null : delims.GetStringDelims());
            if (stringDelims != null)
            {
                foreach (string key in stringDelims.Keys)
                {
                    quotes.Add(key);
                    if (key.Length > maxDelimLen)
                        maxDelimLen = key.Length;
                }
            }

            // parse
            int len = s.Length;
            for (int i = 0; i < len; i++)
            {
                char c = s[i];
                if (inString)
                {
                    if (c == endString)
                    {	// end of string
                        if (current.Length > 0)
                            list.Add(current.ToString());
                        list.Add(c.ToString());
                        inString = inWord = false;
                        atStart = true;
                        current = new StringBuilder();
                    }
                    else
                    {
                        current.Append(c);
                    }
                }
                else if (s_white.IndexOf(c) == -1)
                {	// non-white
                    if (atStart)
                    {
                        atStart = false;
                        string cAsStr = c.ToString();
                        if (quotes.Contains(cAsStr))
                        {	// start of string

                            // find the longest starting delim
                            int additional = 0;
                            for (int j = 1; j < maxDelimLen; j++)
                            {
                                if (i + j + 1 > len)
                                    break;
                                string substr = s.Substring(i, j + 1);
                                if (quotes.Contains(substr))
                                {
                                    cAsStr = substr;
                                    additional = j;
                                }
                            }
                            i += additional;

                            list.Add(cAsStr);
                            //!! should allow multi-char
                            string endDelim = stringDelims[cAsStr].End;
                            endString = (endDelim == null ? '\0' : endDelim[0]);
                            inString = true;
                            continue;
                        }
                    }
                    current.Append(c);
                    inWord = true;
                }
                else if (inWord)
                {	// end of word
                    if (current.Length > 1 && current[current.Length - 1] == ',')
                        // remove trailing comma
                        current.Remove(current.Length-1, 1);
                    list.Add(current.ToString());
                    inWord = false;
                    atStart = true;
                    current = new StringBuilder();
                }
            }

            if (inWord || inString)
                list.Add(current.ToString());

            return list.ToArray();
        }
Exemple #5
0
 public DelimiterList GetCurrentLine(IParseLineDelimiters delims)
 {
     if (m_current >= m_count)
         return null;
     // see if line was already parsed
     DelimiterList parsedLine = (m_current < m_parsedLines.Count ? m_parsedLines[m_current] : null);
     if (parsedLine == null)
     {	// if not, parse it now
         parsedLine = ParseLine.Do(m_lines[m_current], delims);
         m_parsedLines.Add(parsedLine);
     }
     return parsedLine;
 }
Exemple #6
0
 /// <summary>
 /// Creates delimiter list from string.  All delimiters must be closed.
 /// </summary>
 /// <param name="str">line to parse</param>
 /// <param name="delims">used to ask questions about delimiters</param>
 internal static DelimiterList Do(string str, IParseLineDelimiters delims)
 {
     return Do(str, delims, null);
 }
Exemple #7
0
        // handle as individual tokens and nested lists
        private static bool ParseMisc(int indent, string original, string[] strs, int iStart, ValueDelimiter thisDelim,
			IParseLineDelimiters delims, ILineRequestor requestor, List<DelimiterNode> nodes,
			out int iEnd, out DelimiterList result)
        {
            result = null;
            iEnd = strs.Length;

            for (int i = iStart; i < strs.Length; i++)
            {
                string s = strs[i];

                // is this the end of current set of delimited tokens?
                if (s == thisDelim.End)
                {	// end delimiter
                    iEnd = i;
                    string subStr = GetSubStr(iStart, iEnd, strs);
                    result = new DelimiterList(thisDelim, nodes, indent, strs[iStart - 1], subStr, null);
                    return true;
                }
                // TODO: rework this so I don't need to check for : (e.g. for :}, when creating a delim)
                if (s.Substring(s.Length - 1, 1) == thisDelim.End && (s[0] != ':' || s.Length > 2))
                {	// end delimiter is part of final token
                    iEnd = i + 1;
                    string without = s.Substring(0, s.Length - 1);

                    Token token = new Token(without);
                    DelimiterNode node = new DelimiterNodeToken(token);
                    nodes.Add(node);

                    strs[i] = without;
                    string subStr = GetSubStr(iStart, iEnd, strs);
                    result = new DelimiterList(thisDelim, nodes, indent, strs[iStart - 1], subStr, null);
                    strs[i] = s;
                    --iEnd;
                    return true;
                }

                // is it a stand alone starting delimiter?
                bool bAnyToken = false;
                ValueDelimiter subDelim = (delims == null ? null : delims.GetDelim(s, out bAnyToken));
                string[] strsToUse = strs;
                bool bExtra = true;
                if (subDelim == null && !bAnyToken)
                {	// whole thing wasn't a delimiter, function, etc., how about the 1st char?
                    string s1 = s.Substring(0, 1);
                    subDelim = (delims == null ? null : delims.GetDelim(s1, out bAnyToken));
                    if (subDelim != null)
                    {	// copy across array, but break iStart into delim & remainder
                        bExtra = false;
                        strsToUse = new string[strs.Length + 1];
                        for (int j = 0; j < i; j++)
                            strsToUse[j] = strs[j];
                        strsToUse[i] = s1;
                        strsToUse[i + 1] = s.Substring(1);
                        for (int j = i + 1; j < strs.Length; j++)
                            strsToUse[j + 1] = strs[j];
                    }
                }
                if (subDelim != null)
                {	// start delimiter
                    int end;
                    DelimiterList sublist = Do(0, original, strsToUse, i + 1, subDelim, delims, requestor, out end);
                    if (sublist != null)
                    {
                        DelimiterNodeList node = new DelimiterNodeList(sublist);
                        nodes.Add(node);
                    }
                    // skip past the sublist
                    i = (bExtra ? end : end - 1);
                }
                else
                {	// stand alone token
                    Token token = new Token(s);
                    DelimiterNode node = new DelimiterNodeToken(token);
                    nodes.Add(node);
                }
            }
            return false;
        }