Raised This Month: $51 Target: $400
 12% 

[PARSER] Get function info from include files


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Neeeeeeeeeel.-
Some Guy Yellin'
Join Date: Jul 2010
Location: Argentina
Old 05-01-2014 , 14:00   [PARSER] Get function info from include files
Reply With Quote #1

Well, I made a function parser for my own purposes and I want to share it.

It's coded in python, but you can parse the output with any language (manually or using JSON)... it works like a pre-processor, it does the hard work for you.
You can also insert data directly into a database with python without parsing anything.

The software will read all the files in "includes" directory (relative to him) and will get all the information from each function.

Here is the function structure:
Code:
pos 0: include file
pos 1: function name
pos 2: function modifier
pos 3: return type (not exactly a return type, it only shows if there is Float: or something like that before the function name)
pos 4: all the parameters as they are declared
pos 5: params count number
pos 6: a list with each param
        pos 6-0: the whole param as it's declared
        pos 6-1: variable type
        pos 6-2: variable name
        pos 6-3: 1 if the variable is passed by reference, 0 otherwise
        pos 6-4: default value (if there is any)
        pos 6-5: 1 if the variable is optional, 0 otherwise

Example: ['amxmisc.inc', 'cmd_target', 'stock', '', 'id,constarg[],flags=CMDTARGET_OBEY_IMMUNITY', 3, [['id', 'int', 'id', 0, '', 0], ['constarg[]', 'cell[]', 'constarg', 0, '', 0], ['flags=CMDTARGET_OBEY_IMMUNITY', 'int', 'flags', 0, 'CMDTARGET_OBEY_IMMUNITY', 1]]]
Parser code
PHP Code:
import re;
import json;
from os import listdir;
from os.path import isfilejoin;

def getFuncReturnType(line):
    
line re.sub(r"\(.*\)"""line);
    if 
not ":" in line:
        return 
"";
    
line re.sub(r".* (.*):.*"r"\1"line);
    return 
line;

def getFuncName(line):
    return 
re.sub(r".*(?::| )(.*)\(.*"r"\1"line);

def getModifier(line):
    if 
re.compile("stock").match(line):
        return 
"stock";
    
elif re.compile("forward").match(line):
        return 
"forward";
    
elif re.compile("native").match(line):
        return 
"native";

def getFuncParams(line):
    return 
re.sub(r".*\((.*)\).*"r"\1"line);

def getFuncParamsCount(params):
    if 
params == "":
        return 
0;
    return 
len(re.split(",(?!_})"params));
    
def parseParams(params):
    if 
params == "":
        return [];
    
params re.split(",(?!_})"params);
    
temp = [];
    for 
i in params:
        
temp.append(parseParam(i));
    return 
temp;

def parseParam(param):
    
varType "cell";
    
varParam param;
    if 
re.compile("^const ").match(param):
        
varType "const "+varType;
    if 
param[0] == '&':
        
varRef 1;
    else:
        
varRef 0;
    if 
":" in param:
        
temp param.split(':');
        
varType temp[0].replace('&','');
        
param temp[1];
    
varDef param.split('=');
    
varOptional 0;
    if 
len(varDef)>1:
        
varDef varDef[1];
        
varOptional 1;
    else:
        
varDef "";
    
varName re.sub(r"(?:\[[0-9]*(?: char)?\])?(?:=.*)?",""param);
    
temp re.sub(r"(?:=.*)?"""param);
    
temp temp.replace(varName'');
    if 
temp == "":
        
varType re.sub(r"^cell""int"varType);
    else:
        
varType += temp;
    
varName varName.replace('&','');
    if 
"any:..." in varParam:
        
varOptional 1;
    return [
varParamvarTypevarNamevarRefvarDefvarOptional];
    
regex re.compile("^(?:stock |native |forward )");
functions = [];
for 
f in listdir("include"):
    if 
isfile(join("include",f)):
        
fp open("include/"+f"r");
        
lineas fp.readlines();
        print 
f;
        print 
"";
        for 
line in lineas:
            
line line.replace('\n','').replace('\t','').replace('\r','');
            if (
regex.match(line) and "stock const" not in line and not "Float:operator" in line and not "bool:operator" in line):
                
line re.sub(r"\).*"")"line);
                
line re.sub(r"/\*.*\*/"""line);
                
line line.replace(' ','');
                
line re.sub(r"^stock""stock "line);
                
line re.sub(r"^native""native "line);
                
line re.sub(r"^forward""forward "line);
                
funcName getFuncName(line);
                
funcModifier getModifier(line);
                
funcReturnType getFuncReturnType(line);
                
funcParams getFuncParams(line);
                
funcParamsCount getFuncParamsCount(funcParams);
                
funcParamsDetails parseParams(funcParams);
                
data = [ffuncNamefuncModifierfuncReturnTypefuncParamsfuncParamsCountfuncParamsDetails];
                
functions.append(data);
                print 
funcName;
        
fp.close();
        print 
"";
        print 
"";
        print 
"";
readable "";
parseable "";
for 
i in functions:
    
readable += str(i)+"\n";
    for 
k in i:
        if 
type(k) == list:
            for 
x in k:
                for 
j in x:
                    
parseable += str(j)+"!;;;!";
                if 
!= []:
                    
parseable parseable[0:len(parseable)-5];
                    
parseable += "!;;!";
            if 
!= []:
                
parseable parseable[0:len(parseable)-4];
                
parseable += "!;!";
        else:
            
parseable += str(k)+"!;!";
    if 
!= []:
        
parseable parseable[0:len(parseable)-3];

    
parseable += "\n";
fp open("readable-output.txt""w");
fp.write(readable);
fp.close();
fp open("parseable-output.txt""w");
fp.write(parseable);
fp.close();
fp open("json-output.txt""w");
fp.write(json.dumps(functions));
fp.close(); 
It has 3 outputs. I parsed all amxx-cstrike includes
readable-output.txt - Example: http://pastebin.com/uSgYykxM
parseable-output.txt - Example: http://pastebin.com/Q9rMg5ER
json-output.txt - Example: http://pastebin.com/2DYdRkNJ

Here is a php function to parse "parseable-output.txt"
PHP Code:
function fileToArray($file){
    
$data file_get_contents($file);
    
$functions preg_split("/\n/"$data);
    
$fileInArray = Array();
    foreach (
$functions as $funcData){
        
$function preg_split("/!;!/"$funcData);
        foreach (
$function as $func){
            
$funcInfo preg_split("/!;;!/"$func);
            if (
count($funcInfo)>|| stristr($funcInfo[0], "!;;;!")){
                
$temp1 = Array();
                foreach (
$funcInfo as $paramsInfo){
                    
$paramInfo preg_split("/!;;;!/"$paramsInfo);
                    
$temp2 = Array();
                    foreach (
$paramInfo as $paramData){
                        
$temp2[] = $paramData;
                    }
                    
$temp1[] = $temp2;
                }
                
$fileInArray[] = $temp1;
            } else {
                
$fileInArray[] = $funcInfo[0];
            }
        }
    }
    return 
$fileInArray;
}
var_export(fileToArray("parseable-output.txt")); 
Output example (it's a valid php array code): Clic me (I can't upload it to pastebin because it reachs 500kb filezise limitation).

PS: I didn't care about efficience, it could be easily optimizated a lot but I just wanted to code it fast since I will only run it once
__________________

Last edited by Neeeeeeeeeel.-; 05-01-2014 at 14:01.
Neeeeeeeeeel.- is offline
Send a message via Skype™ to Neeeeeeeeeel.-
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 11:07.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode