diff --git a/cplusplus/README.md b/cplusplus/README.md index 2d51e55..275fa65 100644 --- a/cplusplus/README.md +++ b/cplusplus/README.md @@ -2,7 +2,7 @@ A library that that transforms python code into cpp code. -The 'temp.py' file metamorphosed into 'temp.cpp'. +The 'temp.py' file gets metamorphosed into 'temp.cpp'. ## Libraries created @@ -19,4 +19,4 @@ Taking the input and producing output of a script. Extracting text from the code. We get two lists of strings, one is a list of keywords ('print' etc), and a list of texts (the text enclosed in parentheses). -This is not a stable version as exception handling has not been implemented. +Currently, the code is being tested for bugs. diff --git a/cplusplus/extract/extract.py b/cplusplus/extract/extract.py index 031b977..9396ad0 100644 --- a/cplusplus/extract/extract.py +++ b/cplusplus/extract/extract.py @@ -6,6 +6,9 @@ """ import re +import scriptIO + +""" stable """ """ gets the keywords (print etc), and the text within thr parentheses @@ -16,36 +19,184 @@ returns: keywords (list of strings), texts (list of strings) """ -def extractFromScript(text): +def clean_raw_code(text): keywords = [] texts = [] + for line in text: + try: + + if str(line)[0] == '': + continue + """ + get value before the parentheses + """ + keyword = re.compile("(.*?)\s*\(") + flag = re.search("(.*?)\s*\(", line) + if flag is None: + continue + else: + keyword = keyword.match(line) + keyword = keyword.group(1) + keywords.append(keyword) + + """ + get value in the parentheses + """ + text = re.compile(".*?\((.*?)\)") + text = text.match(line) + text = text.group(1) + texts.append(text) + + except: + keywords, texts = -1, -1 + print("An error occurred while applying regular expressions") + raise + + return keywords, texts + +""" stable """ +# returns whether comment exists or not and if yes the column number also +def comment_exists(text): + col = text.find('#') + if(col != -1): + return 1, col + else: + return 0, -1 + + +""" stable """ +""" returns the indices of the rows where code and / or comments are present""" + +def get_indices(script): + + codeRowIndices, commentRowIndices = [], [] + row = 0 + flag, col = 0, 0 + + for line in script: + row += 1 + flag, col = comment_exists(line) + + # check whether comment exists on the line + if(flag): + # add the row number to commentIndices + commentRowIndices.append(row) + if (col > 0): + codeRowIndices.append(row) - """ - get value before the parentheses - """ - keyword = re.compile("(.*?)\s*\(") - keyword = keyword.match(line) - keyword = keyword.group(1) - keywords.append(keyword) - - """ - get value in the parentheses - """ - text = re.compile(".*?\((.*?)\)") - text = text.match(line) - text = text.group(1) - texts.append(text) + # if line has an empty line + elif line == '': + continue - return keywords, texts + else: + codeRowIndices.append(row) + + return commentRowIndices, codeRowIndices + +""" stable """ """ -removes the comments from the python script -def comment(text): - +removes the single line comments from the python script """ +def strip_comments(script): + """ + initializing empty lists to get the comments, + and an empty string to store the comments + """ + comments = [] + comment = '' + row = 0 + + # iterate over the script line by line + for line in script: + + row += 1 + # get single line comments + + if line.find('#') != -1: + + # get where the comment begins in the line + ind = line.find('#') + + + + # isolate commment from the line + comment = (str(line))[ind:] + + # append comment to the list of comments + comments.append(comment) + + + # replacing the comments in script with an empty string + def replaceCharacters(s, unwanted, input_char = ''): + # Iterate over the strings to be replaced + for elem in unwanted: + # Replace the string, does not do anything if `elem` not in `s` + s = s.replace(elem, input_char) + return s + + # call the function + script_new = [replaceCharacters(x, comments) for x in script] + + + # remove all the empty strings in the script_new + raw_code = list(filter(None, script_new)) + + return raw_code, comments + + +""" the code below is the proof of concept for converting python comments to cpp comments """ """ -keywords, texts = extractFromScript(script) +filename = 'temp.py' +script = scriptIO.readScript(filename) +script = list(filter(None, script)) +commentRowIndices, codeRowIndices = get_indices(script) +commentRowIndices.append(-1) +codeRowIndices.append(-1) +raw_code, comments = stripComments(script) +keywords, texts = clean_raw_code(raw_code) +print(texts[0]) +print(str(comments[0])[1:]) +# +def POC(keywords, texts, comments, commentRowIndices, codeRowIndices): + codeIterator, commentIterator = 0, 0 + + len_code = len(keywords) + + len_comments = len(comments) + + while(codeIterator < len_code and commentIterator < len_comments): + if(codeRowIndices[codeIterator] == commentRowIndices[commentIterator]): + + print('print ' + str(texts[codeIterator]) + ' // ' + str(comments[commentIterator])[1:] + '\n') + codeIterator += 1 + commentIterator += 1 + + elif (codeRowIndices[codeIterator] > commentRowIndices[commentIterator]): + + print('// ' + str(comments[commentIterator])[1:] + '\n') + commentIterator += 1 + + elif (codeRowIndices[codeIterator] < commentRowIndices[commentIterator]): + + if keywords[codeIterator] == 'print': + print('print ' + str(texts[codeIterator]) + '\n') + codeIterator += 1 + + + while(commentIterator < len_comments): + print('// ' + str(comments[commentIterator])[1:] + '\n') + commentIterator += 1 + + while(codeIterator < len_code): + if keywords[codeIterator] == 'print': + print('print ' + str(texts[codeIterator]) + '\n') + codeIterator += 1 + + + +POC(keywords, texts, comments, commentRowIndices, codeRowIndices) + """ - \ No newline at end of file diff --git a/cplusplus/helloWorld.cpp b/cplusplus/helloWorld.cpp new file mode 100644 index 0000000..e7f9109 --- /dev/null +++ b/cplusplus/helloWorld.cpp @@ -0,0 +1,9 @@ +#include + +using namespace std; +int main(void){ +// This is a working model for converting python scripts to .cpp files +cout << "\nHello World!" ; // comment 1 +cout << "\nThis is Bhasha" ; // comment 2 +return 0; +} diff --git a/cplusplus/scriptIO/scriptIO.py b/cplusplus/scriptIO/scriptIO.py index 4f27d3a..59e5bcb 100644 --- a/cplusplus/scriptIO/scriptIO.py +++ b/cplusplus/scriptIO/scriptIO.py @@ -1,10 +1,12 @@ -# -*- coding: utf-8 -*- +""" -*- coding: utf-8 -*- """ """ Created on Tue Jun 9 20:49:09 2020 @author: vgadi """ +import sys +""" stable """ """ reads a .py script @@ -12,18 +14,26 @@ 1) filename (string): the name of the file from which text to be extracted -returns: list of strings with newlines split as '\n' +returns: list of strings new lines split with '\n' """ def readScript(filename): - # open file to read - script = open(filename, 'r') - # read the file - script = script.read() - # convert the newlines into '\n' - script = script.split('\n') - return script - - + try: + # open file to read + script = open(filename, 'r') + # read the file + script = script.read() + # convert the newlines into '\n' + script = script.split('\n') + return script + except OSError as err: + print("OS error: {0}".format(err)) + raise + except: + print("Unexpected error: ", sys.exc_info()[0]) + raise + + +""" stable """ """ creating the required file @@ -36,7 +46,10 @@ def readScript(filename): returns: nothing """ def createScript(extension, code, filename = 'helloWorld'): - filename = filename + extension - writeFile = open(filename, 'w') + try: + filename = filename + extension + writeFile = open(filename, 'w') - writeFile = writeFile.write(code) + writeFile = writeFile.write(code) + except: + print("\nAn error occrred while writing to file.") diff --git a/cplusplus/stroustrup.py b/cplusplus/stroustrup.py index a9424db..7a7c0b9 100644 --- a/cplusplus/stroustrup.py +++ b/cplusplus/stroustrup.py @@ -1,82 +1,81 @@ # -*- coding: utf-8 -*- """ Created on Tue Jun 9 19:18:49 2020 - @author: vgadi """ - -""" a homage to bjarne stroustrup, the creator of the c++ language""" - import sys -""" -as the scriptIO library and the extract library are not in the original directory, we add the folders to the system path, so -that the interpreter can search for the files there -""" - sys.path.append('scriptIO') sys.path.append('extract') - -""" -importing the custom libraries -""" - import scriptIO import extract - -""" -importing to iterate over two lists simulateneously -""" import itertools class CPP: # default constructor - def __init__(self, userLibraries = ['iostream'], filename = 'temp.py'): - """ the filename from where the python code is to be read """ - self.filename = filename - - """ the list of c++ libraries to be included """ - self.libraries = userLibraries - - """ an empty string for initializing cpp code """ - self.generatedCode = '' - - """ the extension of the file to be generated """ - self.extension = '.cpp' - - """ to add new lines """ - self.newline = '\n' - - """ an empty string for initializing the cpp libraries """ - self.libCode = '' - """ - the boilerplate syntax for a .cpp file - """ - - # int main() - self.int_main = 'int main(void){' - - """ - as there is a difference in syntax between python and cpp, we have to - write some minor syntax by ourselves - """ - self.semicolon = ' ; ' - self.cout = 'cout << ' - self.starterCode = '' - self.endCode = 'return 0; \n}' - self.coutNewline = "cout << endl;" - - """ generating the code for including the libraries """ - self.__createLibraries__() - - """ including the libraries and also the int main(void) part """ - self.__createStarterCode__() + def __init__(self, user_libraries = ['iostream'], filename = 'temp.py'): + try: + """ empty string which will contain the script read from the python file """ + self.script = '' + """ the filename from where the python code is to be read """ + self.filename = filename + + """ the list of c++ libraries to be included """ + self.libraries = user_libraries + + """ an empty string for initializing cpp code """ + self.generated_code = '' + + """ the extension of the file to be generated """ + self.extension = '.cpp' + + """ to add new lines """ + self.newline = '\n' + + """ comments in python file """ + self.comments = '' + + """ an empty string for initializing the cpp libraries """ + self.lib_code = '' + """ + the boilerplate syntax for a .cpp file + """ + + # int main() + self.int_main = 'int main(void){' + + """ + as there is a difference in syntax between python and cpp, we have to + write some minor syntax by ourselves + """ + self.semicolon = ' ; ' + self.cout = 'cout << ' + self.starter_code = '' + self.end_code = 'return 0; \n}' + self.cout_newline = "cout << endl;" + + except: + print('An unexpected error occurred while creating the class object.') + raise + try: + """ generating the code for including the libraries """ + self.__create_libraries__() + except: + print("An unexpected error occurred while creating the libraries") + raise + + try: + """ including the libraries and also the int main(void) part """ + self.__create_starter_code__() + except: + print("An unexpected error occurred while creating the starter code.") + """ stable """ """ creates the required include library syntax """ - def __createLibraries__(self): + def __create_libraries__(self): includes = [] text = '' # creates the syntax for each library that has to be included to be @@ -90,57 +89,116 @@ def __createLibraries__(self): # adds the library syntax to the actual cpp code for include in includes: - self.libCode += str(include) + self.lib_code += str(include) - self.libCode += self.newline - + self.lib_code += self.newline + """ stable """ """ creates the initial code for the cpp file """ - def __createStarterCode__(self): + def __create_starter_code__(self): """ adding 'using namespace std; ' and 'int main(void){' to the code """ - self.libCode = self.libCode + self.newline + 'using namespace std;' - self.libCode += self.newline + self.int_main - self.starterCode = self.libCode + self.newline - self.generatedCode = self.starterCode + self.lib_code = self.lib_code + self.newline + 'using namespace std;' + self.lib_code += self.newline + self.int_main + self.starter_code = self.lib_code + self.newline + self.generated_code = self.starter_code - + """ stable """ """ - generates the required cpp code, currently supports only print statements + generates the required cpp code, including comments transformed from python to c++ format + currently supports only print statements """ - def generateCode(self): + def generate_code(self): # reading the code written in the script - text = scriptIO.readScript(self.filename) + self.script = scriptIO.readScript(self.filename) + # extracting the comment and the code row indices + comment_row_indices, code_row_indices = extract.get_indices(self.script) + # stripping the script of comments + self.script, self.comments = extract.strip_comments(self.script) # extracting the keywords, and the texts from the code - keywords, texts = extract.extractFromScript(text) - - # zipping the two lists so as to iterate over them simultaneously - for (keyword, text) in zip(keywords, texts): - # currently only support for print() - if str(keyword) == 'print': - - # add 'cout << ', the 'text' extracted, and the semicolon - self.generatedCode += self.cout + str(text) + self.semicolon - # add a newline both in the output of file, as per the .py file - # add a '\n' to increase the readibility the '.cpp' code - self.generatedCode += str(self.coutNewline) + self.newline + keywords, texts = extract.clean_raw_code(self.script) + #def POC(self, keywords, texts, comments, comment_row_indices, code_row_indices): + code_iterator, comment_iterator = 0, 0 + #print(code_row_indices) + #print(comment_row_indices) + # length of the list containing the keyords + len_code = len(keywords) + #print(len_code) + # length of the list containing the comments + len_comments = len(self.comments) + #print(len_comments) + # add comments and code + while(code_iterator < len_code and comment_iterator < len_comments): + + # if the comment is going to be before the code + if (comment_row_indices[comment_iterator] < code_row_indices[code_iterator]): + # add comment to the generated code + self.generated_code += '//' + str(self.comments[comment_iterator])[1:] + # increment comment iterator + comment_iterator += 1 + + # if the code is going to before the comment + elif (code_row_indices[code_iterator] < comment_row_indices[comment_iterator]): + # if keyword is print + if keywords[code_iterator] == 'print': + # add code to the line + self.generated_code += self.cout + ' ' + str(texts[code_iterator]) + str(self.semicolon) + # increment code iterator + code_iterator += 1 - # add a '\n' to increase the readibility the '.cpp' code - self.generatedCode + self.newline + + # if the code and comment is on the same line + elif(code_row_indices[code_iterator] == comment_row_indices[comment_iterator]): + if (keywords[code_iterator] == 'print'): + # add code and comments to the generated code + self.generated_code += self.cout + ' ' + str(texts[code_iterator]) + str(self.semicolon) + ' //' + str(self.comments[comment_iterator])[1:] + # increment code and comment iterator + code_iterator += 1 + comment_iterator += 1 + + # add a newline to the generated code for readibility + self.generated_code += str(self.newline) + + # if code list is completed, add comments + while(comment_iterator < len_comments): + # add comments to the generated code + self.generated_code += '// ' + str(self.comments[comment_iterator])[1:] + # increment comment iterator + comment_iterator += 1 + # add newline to code for readability + self.generated_code += self.newline + + while(code_iterator < len_code): + if keywords[code_iterator] == 'print': + # add code to generated code + self.generated_code += self.cout + ' ' + str(texts[code_iterator]) + str(self.semicolon) + # increment code iterator + code_iterator += 1 + # add newline to code for readability + self.generated_code += str(self.newline) + + + """ stable """ """ write the generated code to a .cpp file """ def write2File(self): + try: + # to the generated code, add the ending lines of a .cpp file + self.generated_code += self.end_code - # to the generated code, add the ending lines of a .cpp file - self.generatedCode += self.endCode - - # create the required '.cpp' file from the generated code - scriptIO.createScript(extension = '.cpp', code = self.generatedCode, filename = 'temp') + # create the required '.cpp' file from the generated code + scriptIO.createScript(extension = '.cpp', code = self.generated_code) + + print("\n.cpp file sucessfully generated!") + + except: + + print("\nThere was an error while creating the file :(") diff --git a/cplusplus/temp.cpp b/cplusplus/temp.cpp deleted file mode 100644 index 2967524..0000000 --- a/cplusplus/temp.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include - -using namespace std; -int main(void){ -cout << "Hello" ; cout << endl; -cout << "World" ; cout << endl; -return 0; -} \ No newline at end of file diff --git a/cplusplus/temp.py b/cplusplus/temp.py index 0086a15..a6e25d6 100644 --- a/cplusplus/temp.py +++ b/cplusplus/temp.py @@ -1,2 +1,3 @@ -print("Hello") -print("World") \ No newline at end of file +# This is a working model for converting python scripts to .cpp files +print("\nHello World!") # comment 1 +print("\nThis is Bhasha") # comment 2