예제 #1
0
        private bool TryReadElementString(string elementName, bool mustEndInWhitespace)
        {
            var fileContents = streamReader.Text;

            var readTo = streamReader.ReadIndex + elementName.Length;
            var eof    = readTo == fileContents.Length;

            if (readTo <= fileContents.Length)
            {
                if (StringEqual(fileContents.Substring(streamReader.ReadIndex, elementName.Length), elementName))
                {
                    if (!mustEndInWhitespace ||
                        eof ||
                        FortranParseHelper.IsWhiteSpace(fileContents[streamReader.ReadIndex + elementName.Length]))
                    {
                        streamReader.ReadIndex += elementName.Length;
                        if (!eof && fileContents[streamReader.ReadIndex] != '\n')
                        {
                            streamReader.ReadIndex += 1; //plus space
                        }
                        return(true);
                    }
                }
            }
            return(false);
        }
        public string FindEffectiveStatementAtOffset(string line, int offsetInLine, out int beginOfStatement)
        {
            var endOfStatement   = offsetInLine - 1;
            var parenthesisLevel = 0;
            int i;
            var statement = new StringBuilder();

            for (i = endOfStatement; i >= 0; i--)
            {
                var c = line[i];

                if (c == ')')
                {
                    if (statement.Length == 0)
                    {
                        break;
                    }
                    parenthesisLevel++;
                }
                else if (parenthesisLevel > 0)
                {
                    //next
                    if (c == '(')
                    {
                        parenthesisLevel--;
                    }
                }
                else
                {
                    if (FortranParseHelper.IsNonStatementCharacter(c))
                    {
                        break;
                    }
                    else
                    {
                        statement.Insert(0, c);
                    }
                }
            }

            beginOfStatement = i + 1;
            var originalBegin = beginOfStatement;

            for (int j = 0; j < statement.Length; j++)
            {
                var c = statement[j];
                if (FortranParseHelper.IsWhiteSpace(c))
                {
                    beginOfStatement++;
                }
                else
                {
                    break;
                }
            }

            return(statement.ToString().Substring(beginOfStatement - originalBegin));
        }
예제 #3
0
        private bool TryReadType(string memberName, SyntaxTree sourceAST, ref IMember parentMember)
        {
            //todo: we're not skipping comments in this code

            if (IsMemberExpected <Type>(parentMember) && TryReadElementString(memberName, false))
            {
                var remainingLine = FortranParseHelper.GetStringUptoEndOfLineOrBeginOfComment(streamReader.Text, streamReader.ReadIndex - 1);
                var skip          = false;

                if (remainingLine.IndexOf("(") >= 0)
                {
                    //type use, not a type declaration
                }
                else
                {
                    var indexOfDoubleDots = remainingLine.IndexOf("::");

                    if (indexOfDoubleDots >= 0)
                    {
                        streamReader.ReadIndex--; //read back one
                        streamReader.ReadIndex += indexOfDoubleDots + 2;
                        char c = streamReader.Text[streamReader.ReadIndex];
                        while (FortranParseHelper.IsWhiteSpace(c)) //skip whitespace
                        {
                            c = streamReader.Text[++streamReader.ReadIndex];
                        }
                    }
                    else
                    {
                        //expect whitespace
                        if (!FortranParseHelper.IsWhiteSpace(streamReader.Text[streamReader.ReadIndex - 1]))
                        {
                            skip = true;
                        }
                    }
                    if (!skip)
                    {
                        var name = streamReader.ReadElementName();
                        if (!String.IsNullOrEmpty(name))
                        {
                            OnMemberFound <Type>(ref parentMember, name, sourceAST);
                            return(true);
                        }
                    }
                }
            }
            return(TryReadEndOfMember <Type>(ref parentMember, memberName));
        }
예제 #4
0
        public string ReadElementName()
        {
            bool nameStarted = false;

            var start = ReadIndex;

            for (ReadIndex = start; ReadIndex < Text.Length; ReadIndex++)
            {
                var c = Text[ReadIndex];

                if (!nameStarted && c == ' ') //skip spaces in front of name
                {
                    start++;
                    continue;
                }

                nameStarted = true;

                if (FortranParseHelper.IsWhiteSpace(c)) //quick loop
                {
                    //end of name
                    break;
                }

                if (!FortranParseHelper.IsWordCharacter(c))
                {
                    //non valid name characters: end of name
                    break;
                }
            }
            if (ReadIndex < Text.Length)
            {
                var name = Text.Substring(start, ReadIndex - start);
                if (!String.IsNullOrEmpty(name))
                {
                    ReadIndex--;
                }
                return(name);
            }
            return("");
        }
예제 #5
0
        public bool SkipToNextPotentialCodeElement()
        {
            if (lastIndexVisited == ReadIndex)
            {
                ReadIndex++; //continue to next character if we already got here
            }

            var start = ReadIndex;

            for (ReadIndex = start; ReadIndex < Text.Length; ReadIndex++)
            {
                var c = Text[ReadIndex];

                if (c == '\n')
                {
                    LineNumber++;
                    StartOfLineIndex = ReadIndex + 1;
                }

                if (FortranParseHelper.IsWhiteSpace(c))
                {
                    continue; //shortcut
                }

                if (!insideCharacterString && c == '"')
                {
                    insideQuoteString = !insideQuoteString; //toggle
                    continue;
                }
                if (!insideQuoteString && c == '\'')
                {
                    insideCharacterString = !insideCharacterString; //toggle
                    continue;
                }

                if (!insideCharacterString && !insideQuoteString)
                {
                    //read comment
                    if (c == '!')
                    {
                        SeekEndOfLine(); //skip comments
                        continue;
                    }

                    if (Style == FortranStyle.Fortran77 && ReadIndex == StartOfLineIndex && (c == 'c' || c == 'C' || c == '*'))
                    {
                        SeekEndOfLine(); //skip comments (f77 style?)
                        continue;
                    }

                    var previousCharWasWhitespace = (ReadIndex > 0) ? FortranParseHelper.IsWhiteSpace(Text[ReadIndex - 1]) : true;

                    if (!previousCharWasWhitespace) //still inside a word
                    {
                        continue;
                    }

                    //this would improve performance and simply some things, but unfortunately the keywords
                    //we're looking for are not always the first word on the line. For example the 'function'
                    //keyword can be prefixed by a type.

                    //if (beginOfLineOnly && lastVisitedLine == LineNumber)
                    //    continue;

                    lastIndexVisited = ReadIndex;
                    return(true);
                }
            }
            return(false); //eof
        }