示例#1
0
        /// <summary>
        /// Matches a procedure definition
        /// </summary>
        private ParsedDestructor CreateParsedDestructor(Token destructorToken, ParsedScope parentScope)
        {
            /*
             * DESTRUCTOR [ PUBLIC ] class-name ( ) :
             * Destructor-body
             */

            // info we will extract from the current statement :
            string    name  = "";
            ParseFlag flags = 0;

            Token token;

            do
            {
                token = PeekAt(1); // next token
                if (token is TokenEos)
                {
                    break;
                }
                if (token is TokenComment)
                {
                    continue;
                }
                if (token is TokenWord)
                {
                    switch (token.Value.ToLower())
                    {
                    case "public":
                        flags |= ParseFlag.Public;
                        break;

                    default:
                        name = token.Value;
                        break;
                    }
                }
            } while (MoveNext());

            if (name == "")
            {
                return(null);
            }

            var newDestructor = new ParsedDestructor(name, destructorToken, parentScope)
            {
                // = end position of the EOS of the statement
                Flags       = flags,
                EndPosition = token.EndPosition
            };

            AddParsedItem(newDestructor, destructorToken.OwnerNumber);

            return(newDestructor);
        }
示例#2
0
        /// <summary>
        /// Parses a list of tokens into a list of parsedItems
        /// </summary>
        public Parser(GapBuffer <Token> tokens, string filePathBeingParsed, ParsedScopeBlock defaultScope, bool matchKnownWords, StringBuilder debugListOut)
        {
            // process inputs
            _filePathBeingParsed = filePathBeingParsed;
            _matchKnownWords     = matchKnownWords && KnownStaticItems != null;

            var rootToken = new TokenEos(null, 0, 0, 0, 0)
            {
                OwnerNumber = 0
            };

            // the first of this list represents the file currently being parsed
            _parsedIncludes.Add(
                new ParsedIncludeFile(
                    "root",
                    rootToken,
                    // the preprocessed variable {0} equals to the filename...
                    new Dictionary <string, string>(StringComparer.CurrentCultureIgnoreCase)
            {
                { "0", Path.GetFileName(FilePathBeingParsed) }
            },
                    _filePathBeingParsed,
                    null)
                );

            // init context
            _context = new ParseContext {
                BlockStack              = new Stack <ParsedScope>(),
                CurrentStatement        = new ParsedStatement(rootToken),
                CurrentStatementIsEnded = true
            };

            // create root item
            var rootScope = defaultScope ?? new ParsedFile("Root", rootToken);

            _context.BlockStack.Push(rootScope);
            if (defaultScope == null)
            {
                AddParsedItem(rootScope, 0);
            }

            // Analyze
            _tokenList  = tokens;
            _tokenCount = _tokenList.Count;
            _tokenPos   = -1;
            ReplaceIncludeAndPreprocVariablesAhead(1); // replaces an include or a preproc var {&x} at token position 0
            ReplaceIncludeAndPreprocVariablesAhead(2); // @position 1
            while (MoveNext())
            {
                try {
                    Analyze();
                } catch (Exception e) {
                    ErrorHandler.LogError(e, "Error while parsing the following file : " + filePathBeingParsed);
                }
            }
            AddLineInfo(_tokenList[_tokenList.Count - 1]); // add info on last line
            PopOneStatementIndentBlock(0);                 // make sure to pop the final block

            // add missing values to the line dictionary
            // missing values will be for the lines within a multilines comment/string for which we didn't match an EOL to add line info
            var currentLineInfo = _lineInfo[_tokenList[_tokenList.Count - 1].Line];

            for (int i = PeekAt(-1).Line - 1; i >= 0; i--)
            {
                if (!_lineInfo.ContainsKey(i))
                {
                    _lineInfo.Add(i, currentLineInfo);
                }
                else
                {
                    currentLineInfo = _lineInfo[i];
                }
            }

            // check for parser errors
            while (_context.BlockStack.Count > 1)
            {
                ParsedScope scope = _context.BlockStack.Pop();
                // check that we match a RESUME for each SUSPEND
                if (scope is ParsedScopePreProcBlock)
                {
                    _parserErrors.Add(new ParserError(ParserErrorType.MissingUibBlockEnd, PeekAt(-1), _context.BlockStack.Count, _parsedIncludes));
                }

                // check that we match an &ENDIF for each &IF
                else if (scope is ParsedScopePreProcIfBlock)
                {
                    _parserErrors.Add(new ParserError(ParserErrorType.MissingPreprocEndIf, PeekAt(-1), _context.BlockStack.Count, _parsedIncludes));
                }

                // check that we match an END. for each block
                else
                {
                    _parserErrors.Add(new ParserError(ParserErrorType.MissingBlockEnd, PeekAt(-1), _context.BlockStack.Count, _parsedIncludes));
                }
            }

            // returns the concatenation of all the tokens once the parsing is done
            if (debugListOut != null)
            {
                foreach (var token in _tokenList)
                {
                    debugListOut.Append(token.Value);
                }
            }

            // dispose
            _context.BlockStack = null;
            _context            = null;
            _tokenList          = null;
            _functionPrototype  = null;
            _parsedIncludes     = null;
            _knownWords         = null;

            // if we are parsing an include file that was saved for later use, update it
            if (SavedTokenizerInclude.ContainsKey(filePathBeingParsed))
            {
                SavedTokenizerInclude.Remove(filePathBeingParsed);
            }
        }
示例#3
0
        /// <summary>
        /// Matches a procedure definition
        /// </summary>
        private ParsedConstructor CreateParsedConstructor(Token constructorToken, ParsedScope parentScope)
        {
            /*
             * CONSTRUCTOR [ PRIVATE | PROTECTED | PUBLIC | STATIC ] class-name
             * ( [ parameter [ , parameter ] ... ] ) :
             * constructor-body
             */

            // info we will extract from the current statement :
            string              name           = "";
            ParseFlag           flags          = 0;
            StringBuilder       parameters     = new StringBuilder();
            List <ParsedDefine> parametersList = null;

            Token token;
            int   state = 0;

            do
            {
                token = PeekAt(1); // next token
                if (token is TokenEos)
                {
                    break;
                }
                if (token is TokenComment)
                {
                    continue;
                }
                switch (state)
                {
                case 0:
                    // default state
                    if (token is TokenWord)
                    {
                        switch (token.Value.ToLower())
                        {
                        case "private":
                            flags |= ParseFlag.Private;
                            break;

                        case "public":
                            flags |= ParseFlag.Public;
                            break;

                        case "protected":
                            flags |= ParseFlag.Protected;
                            break;

                        case "static":
                            flags |= ParseFlag.Static;
                            break;

                        default:
                            name = token.Value;
                            break;
                        }
                    }
                    if (token is TokenSymbol && token.Value.Equals("("))
                    {
                        state = 1;
                    }
                    break;

                case 1:
                    // read parameters, define a ParsedDefineItem for each
                    parametersList = GetParsedParameters(constructorToken, parameters);
                    state          = 2;
                    break;
                }
            } while (MoveNext());

            if (state < 1)
            {
                return(null);
            }

            var newConstructor = new ParsedConstructor(name, constructorToken, parentScope)
            {
                // = end position of the EOS of the statement
                Flags       = flags,
                EndPosition = token.EndPosition
            };

            if (parametersList != null)
            {
                newConstructor.Parameters = new List <ParsedDefine>();
                foreach (var parsedItem in parametersList)
                {
                    newConstructor.Parameters.Add(parsedItem);
                }
            }
            AddParsedItem(newConstructor, constructorToken.OwnerNumber);

            return(newConstructor);
        }
示例#4
0
        /// <summary>
        /// Matches a procedure definition
        /// </summary>
        private ParsedMethod CreateParsedMethod(Token methodToken, ParsedScope parentScope)
        {
            /*
             * METHOD [ PRIVATE | PROTECTED | PUBLIC ] [ STATIC | ABSTRACT ]
             *  [ OVERRIDE ] [ FINAL ]
             *  { VOID | return-type } method-name
             *  ( [ parameter [ , parameter ] ... ] ) :
             */

            // info we will extract from the current statement :
            string              name             = "";
            string              parsedReturnType = "CLASS";
            ParseFlag           flags            = 0;
            StringBuilder       parameters       = new StringBuilder();
            List <ParsedDefine> parametersList   = null;

            Token token;
            int   state = 0;

            do
            {
                token = PeekAt(1); // next token
                if (token is TokenEos)
                {
                    break;
                }
                if (token is TokenComment)
                {
                    continue;
                }
                switch (state)
                {
                case 0:
                    // default state
                    if (token is TokenWord)
                    {
                        switch (token.Value.ToLower())
                        {
                        case "private":
                            flags |= ParseFlag.Private;
                            break;

                        case "public":
                            flags |= ParseFlag.Public;
                            break;

                        case "protected":
                            flags |= ParseFlag.Protected;
                            break;

                        case "static":
                            flags |= ParseFlag.Static;
                            break;

                        case "abstract":
                            flags |= ParseFlag.Abstract;
                            break;

                        case "override":
                            flags |= ParseFlag.Override;
                            break;

                        case "final":
                            flags |= ParseFlag.Final;
                            break;

                        case "void":
                        case "class":
                        case "character":
                        case "integer":
                        case "int64":
                        case "decimal":
                        case "date":
                        case "datetime":
                        case "datetime-tz":
                        case "handle":
                        case "logical":
                        case "longchar":
                        case "memptr":
                        case "recid":
                        case "rowid":
                        case "raw":
                            parsedReturnType = token.Value.ToUpper();
                            break;

                        default:
                            name = token.Value;
                            break;
                        }
                    }
                    if (token is TokenSymbol && token.Value.Equals("("))
                    {
                        state = 1;
                    }
                    break;

                case 1:
                    // read parameters, define a ParsedDefineItem for each
                    parametersList = GetParsedParameters(methodToken, parameters);
                    state          = 2;
                    break;
                }
            } while (MoveNext());

            if (state < 1)
            {
                return(null);
            }

            var newMethod = new ParsedMethod(name, methodToken, parentScope, parsedReturnType)
            {
                // = end position of the EOS of the statement
                Flags       = flags,
                EndPosition = token.EndPosition
            };

            if (parametersList != null)
            {
                newMethod.Parameters = new List <ParsedDefine>();
                foreach (var parsedItem in parametersList)
                {
                    newMethod.Parameters.Add(parsedItem);
                }
            }
            AddParsedItem(newMethod, methodToken.OwnerNumber);

            return(newMethod);
        }