Ejemplo n.º 1
0
    public void includeAnalysis(string text, ref List <functionData> functionList)
    {
        List <string>       errorList = new List <string>();
        List <lexicalToken> tokens    = lexicalAnalysis(text, ref errorList);
        int max = tokens.Count;

        for (int i = 0; i != tokens.Count; i++)
        {
            lexicalToken t = tokens[i];
            if (t.type == tokenType.identifer)
            {
                //Abort if callback:
                if (lexicalHelper.isCallback(t.value))
                {
                    continue;
                }
                //Skip keywords like if (they look like functions):
                if (lexicalHelper.isKeyword(t.value))
                {
                    //Skip until all () are closed again
                    i++; if (i == max)
                    {
                        break;
                    }
                    t = tokens[i];
                    if (t.type == tokenType.parenthesis_open)
                    {
                        int parenthesis_count = 1;
                        while (parenthesis_count != 0)
                        {
                            i++; if (i == max)
                            {
                                break;
                            }
                            t = tokens[i];
                            if (t.type == tokenType.parenthesis_open)
                            {
                                parenthesis_count++;
                            }
                            else if (t.type == tokenType.parenthesis_close)
                            {
                                parenthesis_count--;
                            }
                        }
                    }
                    else
                    {
                        //Error: Expected parenthesis
                    }
                }
                else
                {
                    //Check if the identifer is a function identifer:
                    //Create variables:
                    functionData function = new functionData();
                    function.identifer = t.value;
                    int beginning_token = i;

                    //Check if identifer is a function:
                    i++; if (i == max)
                    {
                        break;
                    }
                    t = tokens[i];
                    //There is a ( following:
                    if (t.type == tokenType.parenthesis_open)
                    {
                        //Add all arguments until all () are closed again:
                        int parenthesis_count = 1;
                        while (parenthesis_count != 0)
                        {
                            i++; if (i == max)
                            {
                                break;
                            }
                            t = tokens[i];
                            if (t.type == tokenType.parenthesis_open)
                            {
                                parenthesis_count++;
                            }
                            else if (t.type == tokenType.parenthesis_close)
                            {
                                parenthesis_count--;
                            }
                            else if (t.type == tokenType.identifer)
                            {
                                function.arguments.Add(t.value);
                            }
                            else if (t.type == tokenType.brace_open || t.type == tokenType.brace_close)
                            {
                                break;
                            }
                        }
                        if (parenthesis_count != 0)
                        {
                            if (i == max)
                            {
                                //Error: File ended unexpectedly!
                                break;
                            }
                            else //The loop broke because of a { or }
                            {
                                //Error: Probably missing at least one ")"
                            }
                        }
                        //Proceed to next tokens:
                        //Skip all unnessecary tokens:
                        do
                        {
                            i++; if (i == max)
                            {
                                break;
                            }
                            t = tokens[i];
                        }while (t.type == tokenType.newline);
                        functionData foundFunction = functionList.Find(item => item.identifer == function.identifer);
                        //Proceed to next tokens:
                        if (t.type == tokenType.brace_open)
                        {
                            //We found the implementation of the function:
                            if (foundFunction != null)
                            {
                                //Error: Function redefinition?
                                continue;
                            }
                            //If the function is a callback implementation, abort:
                            if (lexicalHelper.isCallback(function.identifer))
                            {
                                continue;
                            }
                            function.isImplemented  = true;
                            function.implementation = t.line - 1;
                        }
                        else if (t.type == tokenType.semicolon)
                        {
                            //We found no implementation of the function:
                            //Abort (there could be natives)
                            function.isImplemented  = false;
                            function.implementation = -1;
                        }
                        else
                        {
                            //Error: Missing semicolon:
                        }
                        //Get tags and add to list:
                        int           j            = beginning_token;
                        List <string> dataTypeList = new List <string>();
                        do
                        {
                            j--;
                            if (j <= 0)
                            {
                                break;
                            }
                            t = tokens[j];
                            if (!((t.type == tokenType.newline) || (t.type == tokenType.semicolon)))
                            {
                                dataTypeList.Add(t.value);
                            }
                        }while (j > 0 && t.type != tokenType.newline && t.type != tokenType.semicolon);
                        if (dataTypeList.Count > 0)
                        {
                            function.dataTypes = dataTypeList;
                        }
                        //Add to list or update on list:
                        if (dataTypeList.Find(item => item.Contains("native")) != null)
                        {
                            string arg = "(";
                            foreach (string x in function.arguments)
                            {
                                arg += x + ",";
                            }
                            arg += ")";
                            arg  = arg.Replace(",)", ")");
                            function.fullIdentifer = function.identifer + arg;
                            arg = "";
                            foreach (string x in function.dataTypes)
                            {
                                arg  = arg.Replace("\n", "");
                                arg += x + " ";
                            }
                            function.fullIdentiferDataTypes = arg + function.fullIdentifer;
                            functionList.Add(function);
                        }
                        else
                        {
                            continue;
                        }
                        //Else: Function is a prototype that is no native. Not interested in those.
                    }
                    else
                    {
                        //There is no ( following to the identifer:
                        i--;
                    }
                }
            }
        }
    }
Ejemplo n.º 2
0
    List <lexicalToken> lexicalAnalysis(string text, ref List <string> errorList)
    {
        List <lexicalToken> tokens = new List <lexicalToken>();

        //Current character:
        int i = 0;
        //Different modes:
        const ushort mode_none            = 0;
        const ushort mode_identifer       = 1;
        const ushort mode_operator        = 2;
        const ushort mode_number          = 3;
        const ushort mode_symbol          = 4;
        const ushort mode_comment_entry   = 5;
        const ushort mode_comment_simple  = 6;
        const ushort mode_comment_complex = 7;
        const ushort mode_string          = 8;
        ushort       mode = mode_none;
        //Temporary variables:
        string temp = "";
        char   c;
        bool   expectingEscapeCharacter = false;
        int    currentLine = 0;

        //Scan the text:
        while (i != text.Length)
        {
            c = text[i];
            if (c == '\n')
            {
                currentLine++;
            }
            switch (mode)
            {
            case mode_none:
                if (lexicalHelper.isIdentiferChar(c))       //Start reading identifers
                {
                    mode = mode_identifer;
                }
                else if (lexicalHelper.isNumericChar(c))        //Start reading numbers
                {
                    mode = mode_number;
                }
                else if (c == '/')      //There might be a comment following
                {
                    mode = mode_comment_entry;
                }
                else if (lexicalHelper.isOperatorChar(c))       //Start reading operators
                {
                    mode = mode_operator;
                }
                else if (lexicalHelper.isSymbol(c))     //Start reading symbols
                {
                    mode = mode_symbol;
                }
                else if (c == '\n' || c == '\r')
                {
                    lexicalToken t = new lexicalToken(tokenType.newline, "\n", currentLine);
                    tokens.Add(t);
                    i++;
                }
                else if (c == '\"')
                {
                    mode = mode_string;
                    i++;
                }
                else
                {
                    i++;
                }
                break;

            /*
             * Identifers
             */
            case mode_identifer:
                //If there are still identifer chars being read, continue
                if (lexicalHelper.isIdentiferChar(c) || lexicalHelper.isNumericChar(c))
                {
                    temp += c;
                    i++;
                }
                //Streak is broken, abort and save:
                else
                {
                    lexicalToken token = new lexicalToken(tokenType.identifer, temp, currentLine);
                    tokens.Add(token);
                    temp = "";
                    mode = mode_none;
                }
                break;

            case mode_number:
                //If there are still numeric chars being read, continue
                if (lexicalHelper.isNumericChar(c))
                {
                    temp += c;
                    i++;
                }
                //Streak is broken, abort and save:
                else
                {
                    lexicalToken token = new lexicalToken(tokenType.number, temp, currentLine);
                    tokens.Add(token);
                    temp = "";
                    mode = mode_none;
                }
                break;

            case mode_comment_entry:
                //A / was read! If there is another / oder a * following, we've got a comment!
                i++;
                if (i == text.Length)  //Text suddenly ended...
                {
                    break;
                }
                //Next character:
                c = text[i];
                if (c == '/')
                {
                    //Simple one-line comment
                    mode = mode_comment_simple;
                    i++;
                }
                else if (c == '*')
                {
                    //Multi line comment:
                    mode = mode_comment_complex;
                    i++;
                }
                else
                {
                    //No comment. Let the operator mode handle the situation!
                    temp = "/";
                    mode = mode_operator;
                }
                break;

            case mode_comment_simple:
                //Skip until newline char
                if (c == '\n')
                {
                    mode = mode_none;
                    i++;
                }
                else
                {
                    i++;
                }
                break;

            case mode_comment_complex:
                //Skip until */ is found
                if (c == '*')
                {
                    i++;
                    if (i == text.Length)
                    {
                        break;
                    }
                    c = text[i];
                    if (c == '/')
                    {
                        mode = mode_none;
                        i++;
                    }
                }
                else
                {
                    i++;
                }
                break;

            case mode_operator:
                if (lexicalHelper.isOperatorChar(c))
                {
                    temp += c;
                    i++;
                }
                else
                {
                    lexicalToken token = new lexicalToken(tokenType.op, temp, currentLine);
                    tokens.Add(token);
                    temp = "";
                    mode = mode_none;
                }
                break;

            case mode_symbol:
                if (lexicalHelper.isSymbol(c))
                {
                    lexicalToken token = new lexicalToken(tokenType.symbol, c.ToString(), currentLine);
                    tokens.Add(token);
                    i++;
                    mode = mode_none;
                }
                break;

            case mode_string:
                if (c == '\"')
                {
                    lexicalToken token = new lexicalToken(tokenType.tstring, temp, currentLine);
                    tokens.Add(token);
                    temp = "";
                    mode = mode_none;
                    i++;
                }
                else if (c == '\\')
                {
                    if (!expectingEscapeCharacter)
                    {
                        expectingEscapeCharacter = true;
                    }
                    i++;
                }
                else
                {
                    temp += c;
                    if (expectingEscapeCharacter)
                    {
                        expectingEscapeCharacter = false;
                    }
                    i++;
                }
                break;
            }
        }
        return(tokens);
    }
Ejemplo n.º 3
0
    public void codeAnalysis(string text, ref List <defineData> defineList, ref List <functionData> functionList, bool skipCallbacks = true)
    {
        List <string>       errorList = new List <string>();
        List <lexicalToken> tokens    = lexicalAnalysis(text, ref errorList);

        defineList   = new List <defineData>();
        functionList = new List <functionData>();

        List <functionCallData> functionCallDataList = new List <functionCallData>();

        int max = tokens.Count;

        for (int i = 0; i != tokens.Count; i++)
        {
            lexicalToken t = tokens[i];
            if (t.type == tokenType.define)
            {
                //Create new define object:
                defineData define = new defineData();
                //Proceed to next token:
                i++; if (i == max)
                {
                    break;
                }
                t = tokens[i];
                //If the token is a identifer, add that to the define object:
                if (t.type == tokenType.identifer)
                {
                    define.identifer = t.value;
                }
                else
                {
                    //Error: No define identifer found!
                    errorList.Add("Missing define identifer.");
                    continue;
                }
                // Add all following tokens to the define value:
                do
                {
                    i++; if (i == max)
                    {
                        break;
                    }
                    t             = tokens[i];
                    define.value += t.value + " ";
                }while (t.type != tokenType.newline);
                //Add the define object to the list:
                defineList.Add(define);
            }
            else if (t.type == tokenType.identifer)
            {
                //Abort if callback:
                if (skipCallbacks && lexicalHelper.isCallback(t.value))
                {
                    continue;
                }
                //Skip keywords like if (they look like functions):
                if (lexicalHelper.isKeyword(t.value))
                {
                    //Skip until all () are closed again
                    i++; if (i == max)
                    {
                        break;
                    }
                    t = tokens[i];
                    if (t.type == tokenType.parenthesis_open)
                    {
                        int parenthesis_count = 1;
                        while (parenthesis_count != 0)
                        {
                            i++; if (i == max)
                            {
                                break;
                            }
                            t = tokens[i];
                            if (t.type == tokenType.parenthesis_open)
                            {
                                parenthesis_count++;
                            }
                            else if (t.type == tokenType.parenthesis_close)
                            {
                                parenthesis_count--;
                            }
                        }
                    }
                    else
                    {
                        //Error: Expected parenthesis
                    }
                }
                else
                {
                    //Check if the identifer is a function identifer:
                    //Create variables:
                    functionData function = new functionData();
                    function.identifer = t.value;
                    int beginning_token = i;

                    //Check if identifer is a function:
                    i++; if (i == max)
                    {
                        break;
                    }
                    t = tokens[i];

                    //There is a ( following:
                    if (t.type == tokenType.parenthesis_open)
                    {
                        int identiferLine = t.line; //Line on which the identifer lies.
                        //Add all arguments until all () are closed again:
                        int parenthesis_count = 1;
                        while (parenthesis_count != 0)
                        {
                            i++; if (i == max)
                            {
                                break;
                            }
                            t = tokens[i];
                            if (t.type == tokenType.parenthesis_open)
                            {
                                parenthesis_count++;
                            }
                            else if (t.type == tokenType.parenthesis_close)
                            {
                                parenthesis_count--;
                            }
                            else if (t.type == tokenType.identifer)
                            {
                                function.arguments.Add(t.value);
                            }
                            else if (t.type == tokenType.brace_open || t.type == tokenType.brace_close)
                            {
                                break;
                            }
                        }
                        if (parenthesis_count != 0)
                        {
                            if (i == max)
                            {
                                //Error: File ended unexpectedly!
                                break;
                            }
                            else //The loop broke because of a { or }
                            {
                                //Error: Probably missing at least one ")"
                            }
                        }
                        //Proceed to next tokens:
                        //Skip all unnessecary tokens:
                        do
                        {
                            i++; if (i == max)
                            {
                                break;
                            }
                            t = tokens[i];
                        }while (t.type == tokenType.newline);
                        functionData foundFunction = functionList.Find(item => item.identifer == function.identifer);
                        //Proceed to next tokens:
                        if (t.type == tokenType.brace_open)
                        {
                            //We found the implementation of the function:
                            if (foundFunction != null)
                            {
                                //Error: Function redefinition?
                                continue;
                            }
                            //If the function is a callback implementation, abort:
                            if (lexicalHelper.isCallback(function.identifer))
                            {
                                continue;
                            }
                            function.isImplemented  = true;
                            function.implementation = identiferLine;
                        }
                        else if (t.type == tokenType.semicolon)
                        {
                            //We found no implementation of the function:
                            functionCallData foundFunctionData = functionCallDataList.Find(item => item.identifer == function.identifer);
                            if (foundFunctionData != null)
                            {
                                foundFunctionData.calls.Add(identiferLine);
                            }
                            else
                            {
                                foundFunctionData           = new functionCallData();
                                foundFunctionData.identifer = function.identifer;
                                foundFunctionData.calls.Add(identiferLine);
                                functionCallDataList.Add(foundFunctionData);
                            }
                            continue;
                        }
                        else
                        {
                            //Error: Missing semicolon:
                        }
                        //Get tags and add to list:
                        int           j            = beginning_token;
                        List <string> dataTypeList = new List <string>();
                        do
                        {
                            j -= 2;
                            if (j <= 0)
                            {
                                break;
                            }
                            t = tokens[j];
                            if (!((t.type == tokenType.newline) || (t.type == tokenType.semicolon)))
                            {
                                dataTypeList.Add(t.value);
                            }
                        }while (j > 0 && t.type != tokenType.newline && t.type != tokenType.semicolon);
                        if (dataTypeList.Count > 0)
                        {
                            function.dataTypes = dataTypeList;
                        }
                        if (!function.isImplemented)
                        {
                            continue;
                        }
                        //Add to list or update on list:
                        //Process arguments:
                        string arg = "(";
                        foreach (string x in function.arguments)
                        {
                            arg += x + ",";
                        }
                        arg += ")";
                        arg  = arg.Replace(",)", ")");
                        function.fullIdentifer = function.identifer + arg;
                        arg = "";
                        foreach (string x in function.dataTypes)
                        {
                            arg  = arg.Replace("\n", "");
                            arg += x + " ";
                        }
                        function.fullIdentiferDataTypes = arg + function.fullIdentifer;
                        functionList.Add(function);
                    }
                    else
                    {
                        //There is no ( following to the identifer:
                        i--;
                    }
                }
            }
        }
        foreach (functionCallData i in functionCallDataList)
        {
            functionData f = functionList.Find(item => item.identifer == i.identifer);
            if (f != null)
            {
                f.occurences = i.calls;
            }
        }
    }