Green refactoring: Introduced CommentParser namespace, moved private functions to comments.cpp, minor coding style fixes

This commit is contained in:
Marius Kintel 2016-09-22 11:53:12 -04:00
parent 7f8c969886
commit 1fe45d659a
9 changed files with 239 additions and 300 deletions

View file

@ -1,291 +1,244 @@
#include "comment.h" #include "comment.h"
#include "expression.h"
/* #include <string>
Insert Parameters in AST of given scad file #include <vector>
in form of annotations
*/
void addParameter(const char *fulltext, class FileModule *root_module){
//Getting list of all group names in the file struct GroupInfo {
GroupList groupList = collectGroups(std::string(fulltext)); std::string commentString;
int lineNo;
};
for (AssignmentList::iterator it = root_module->scope.assignments.begin();it != root_module->scope.assignments.end();it++) { typedef std::vector <GroupInfo> GroupList;
//get loaction of assignment node
const Location locate=(*it).location();
int loc =locate.firstLine();
if(!it->expr.get()->isLiteral()){
continue;
}
// makeing list to add annotations
AnnotationList *annotationList = new AnnotationList();
AssignmentList *assignmentList;
//extracting the parameter
string name = getParameter(std::string(fulltext),loc);
//getting the node for parameter annnotataion
assignmentList=parser(name.c_str());
if(assignmentList==NULL){
assignmentList=new AssignmentList();
Expression *expr;
expr=new Literal(ValuePtr(std::string("")));
Assignment *assignment;
assignment=new Assignment("", shared_ptr<Expression>(expr));
assignmentList->push_back(*assignment);
}
const Annotation *Parameter;
Parameter=Annotation::create("Parameter",*assignmentList);
// adding parameter to the list
annotationList->push_back(*Parameter);
//extracting the description /*!
name = getDescription(std::string(fulltext),loc-1);
if(name!= ""){
//creating node for description
assignmentList=new AssignmentList();
Expression *expr;
expr=new Literal(ValuePtr(std::string(name.c_str())));
Assignment *assignment;
assignment=new Assignment("", shared_ptr<Expression>(expr));
assignmentList->push_back(*assignment);
const Annotation * Description;
Description=Annotation::create("Description", *assignmentList);
annotationList->push_back(*Description);
}
// Look for the group to which the given assignment belong
int i=0;
for( ;i<groupList.size() && groupList[i].lineNo<loc;i++){
}
i--;
if(i>=0){
//creating node for description
assignmentList=new AssignmentList();
Expression *expr;
expr=new Literal(ValuePtr(groupList[i].commentString));
Assignment *assignment;
assignment=new Assignment("", shared_ptr<Expression>(expr));
assignmentList->push_back(*assignment);
const Annotation * Description;
Description=Annotation::create("Group", *assignmentList);
annotationList->push_back(*Description);
}
(*it).add_annotations(annotationList);
}
}
/*
gives the string parameter for given gives the string parameter for given
Assignment Assignment
*/
string getParameter(string fulltext, int loc){
Finds the given line in the given source code text, and
extracts the comment (excluding the "//" prefix)
*/
static std::string getParameter(std::string fulltext, int line)
{
if (line < 1) return "";
// Locate line
unsigned int start = 0; unsigned int start = 0;
if( loc<1){ for (; start<fulltext.length() ; start++) {
return ""; if (fulltext[start] == '\n') line--;
} if (line <= 1) break;
for(; start<fulltext.length() ; start++){
if(fulltext[start]=='\n')
loc--;
if(loc<=1)
break;
} }
int end=start+1; int end = start + 1;
while(fulltext[end]!='\n'){ while (fulltext[end] != '\n') end++;
end++;
std::string comment = fulltext.substr(start, end - start);
// Locate comment
unsigned int startText = 0;
int noOfSemicolon = 0;
bool isComment = true;
for (;startText < comment.length() - 1 ; startText++) {
if (comment[startText] == '"') isComment = !isComment;
if (isComment) {
if (comment.compare(startText, 2, "//") == 0) break;
if (comment[startText] == ';' && noOfSemicolon > 0) return "";
if (comment[startText] == ';') noOfSemicolon++;
}
} }
string comment = fulltext.substr(start,end-start); if (startText + 2 > comment.length()) return "";
unsigned int startText=0;
int noOfSemicolon=0;
bool isComment=true;
for(;startText<comment.length()-1;startText++){
if(comment[startText]=='\"'){
isComment=!isComment;
}
if( comment[startText]== '/' && comment[startText+1]=='/' && isComment){
break;
}
if(comment[startText]== ';' && isComment && noOfSemicolon>0){
return "";
}
if(comment[startText]== ';' && isComment){
noOfSemicolon++;
}
}
if(startText+2>comment.length()){
return "";
}
return comment.substr(startText+2);
return comment.substr(startText + 2);
} }
/* /*
Gives the string of Description for given Gives the string of Description for given
Assignment Assignment
*/ */
string getDescription(string fulltext, int loc){ static std::string getDescription(std::string fulltext, int loc)
{
if (loc < 1) return "";
unsigned int start = 0; unsigned int start = 0;
if( loc<1){ for (; start<fulltext.length() ; start++) {
return ""; if (loc <= 1) break;
if (fulltext[start] == '\n') loc--;
} }
for(; start<fulltext.length() ; start++){ // not a valid description
if (fulltext.compare(start, 2, "//") != 0) return "";
if(loc<=1) // Jump over the two forward slashes
break; start = start+2;
if(fulltext[start]=='\n')
loc--;
}
//not a valid description
if(fulltext[start] != '/' || fulltext[start+1] != '/'){
return "";
}
//Jump over the two forward slashes
start=start+2;
//Jump over all the spaces //Jump over all the spaces
while(fulltext[start]==' ' || fulltext[start]=='\t'){ while (fulltext[start] == ' ' || fulltext[start] == '\t') start++;
start++; std::string retString = "";
}
string retString = "";
//go till the end of the line
while(fulltext[start]!='\n'){
//replace // with space
if(fulltext[start] == '/' && fulltext[start+1] == '/'){
// go till the end of the line
while (fulltext[start] != '\n') {
// replace // with space
if (fulltext.compare(start, 2, "//") == 0) {
retString += " "; retString += " ";
start++; start++;
}else{ } else {
retString += fulltext[start]; retString += fulltext[start];
} }
start++; start++;
} }
return retString; return retString;
} }
/* /*
This function collect the list of groups of Parameter decsibred in This function collect the list of groups of Parameter decsibred in
scad file scad file
*/ */
GroupList collectGroups(string fulltext){ static GroupList collectGroups(std::string fulltext)
{
GroupList groupList; //container of all group names GroupList groupList; //container of all group names
int lineNo=1; // tracks line number int lineNo = 1; // tracks line number
bool isComment=true; //check if its string or comment bool isComment = true; //check if its string or comment
//iterate through whole scad file //iterate through whole scad file
for(unsigned int i=0; i<fulltext.length(); i++){ for (unsigned int i=0; i<fulltext.length(); i++) {
//increase line number //increase line number
if(fulltext[i]=='\n'){ if (fulltext[i] == '\n') {
lineNo++; lineNo++;
continue; continue;
} }
//start or end of string negate the checkpoint //start or end of string negate the checkpoint
if(fulltext[i]=='\"'){ if (fulltext[i] == '"') {
isComment=!isComment; isComment = !isComment;
continue; continue;
} }
if(fulltext[i]=='/' && fulltext[i+1]=='/'){ if (fulltext.compare(i, 2, "//") == 0) {
i++; i++;
while(fulltext[i]!='\n'){ while (fulltext[i] != '\n') i++;
i++;
}
lineNo++; lineNo++;
continue; continue;
} }
//start of multi line comment if check is true //start of multi line comment if check is true
if(fulltext[i]=='/' && fulltext[i+1]=='*' && isComment){ if (isComment && fulltext.compare(i, 2, "/*") == 0) {
//store comment //store comment
string comment; std::string comment;
i=i+2; i += 2;
// till */ every character is comment // till */ every character is comment
while(fulltext[i]!='*' && fulltext[i+1]!='/'){ while (fulltext.compare(i, 2, "*/") != 0) {
comment+=fulltext[i]; comment += fulltext[i];
i++; i++;
} }
//store info related to group //store info related to group
GroupInfo groupInfo; GroupInfo groupInfo;
string finalGroupName; //Final group name std::string finalGroupName; //Final group name
string groupName; //group name std::string groupName; //group name
bool isGroupName=false; bool isGroupName = false;
for(unsigned int it=0; it<comment.length();it++){ for (unsigned int it = 0; it < comment.length();it++) {
//Start of Group Name //Start of Group Name
if(comment[it]=='[' ){ if (comment[it] == '[') {
isGroupName=true; isGroupName = true;
continue; continue;
} }
//End of Group Name //End of Group Name
if(comment[it]==']' ){ if (comment[it] == ']') {
isGroupName=false; isGroupName = false;
//Setting of group name //Setting of group name
if(!finalGroupName.empty()){ if (!finalGroupName.empty()) {
finalGroupName=finalGroupName+"-"+groupName; finalGroupName = finalGroupName + "-" + groupName;
}else{ } else {
finalGroupName=finalGroupName+groupName; finalGroupName = finalGroupName + groupName;
} }
groupName.clear(); groupName.clear();
continue; continue;
} }
//collect characters if it belong to group name //collect characters if it belong to group name
if(isGroupName){ if (isGroupName) {
groupName+=comment[it]; groupName += comment[it];
} }
} }
groupInfo.commentString=finalGroupName; groupInfo.commentString = finalGroupName;
groupInfo.lineNo=lineNo; groupInfo.lineNo = lineNo;
groupList.push_back(groupInfo); groupList.push_back(groupInfo);
} }
} }
return groupList; return groupList;
} }
/*!
Insert Parameters in AST of given scad file
form of annotations
*/
void CommentParser::addParameter(const char *fulltext, FileModule *root_module)
{
// Getting list of all group names in the file
GroupList groupList = collectGroups(std::string(fulltext));
for (auto &assignment : root_module->scope.assignments) {
if (!assignment.expr.get()->isLiteral()) continue; // Only consider literals
// get location of assignment node
int firstLine = assignment.location().firstLine();
// making list to add annotations
AnnotationList *annotationList = new AnnotationList();
// extracting the parameter
std::string name = getParameter(std::string(fulltext), firstLine);
// getting the node for parameter annnotataion
AssignmentList *assignmentList = CommentParser::parser(name.c_str());
if (assignmentList == NULL) {
assignmentList = new AssignmentList();
Expression *expr = new Literal(ValuePtr(std::string("")));
Assignment *assignment = new Assignment("", shared_ptr<Expression>(expr));
assignmentList->push_back(*assignment);
}
const Annotation *parameter = Annotation::create("Parameter",*assignmentList);
// adding parameter to the list
annotationList->push_back(*parameter);
//extracting the description
name = getDescription(std::string(fulltext), firstLine-1);
if (name != "") {
//creating node for description
assignmentList = new AssignmentList();
Expression *expr = new Literal(ValuePtr(std::string(name.c_str())));
Assignment *assignment = new Assignment("", shared_ptr<Expression>(expr));
assignmentList->push_back(*assignment);
const Annotation *description = Annotation::create("Description", *assignmentList);
annotationList->push_back(*description);
}
// Look for the group to which the given assignment belong
int i=0;
for (;i<groupList.size() && groupList[i].lineNo<firstLine;i++);
i--;
if (i >= 0) {
//creating node for description
assignmentList = new AssignmentList();
Expression *expr = new Literal(ValuePtr(groupList[i].commentString));
Assignment *assignment = new Assignment("", shared_ptr<Expression>(expr));
assignmentList->push_back(*assignment);
const Annotation * description = Annotation::create("Group", *assignmentList);
annotationList->push_back(*description);
}
assignment.add_annotations(annotationList);
}
}

View file

@ -1,26 +1,14 @@
#ifndef COMMENT_H #ifndef COMMENT_H
#define COMMENT_H #define COMMENT_H
#include "expression.h"
#include"Assignment.h"
#include "FileModule.h" #include "FileModule.h"
#include <string> #include "Assignment.h"
#include<vector>
using namespace std; namespace CommentParser {
extern AssignmentList * parser(const char *text); AssignmentList *parser(const char *text);
void addParameter(const char *fulltext, FileModule *root_module);
struct GroupInfo{ }
string commentString;
int lineNo;
};
typedef vector <GroupInfo> GroupList;
GroupList collectGroups(string fulltext);
string getParameter(string fulltext, int loc);
string getDescription(string fulltext, int loc);
void addParameter(const char *fulltext, class FileModule *root_module);
#endif // COMMENT_H #endif // COMMENT_H

View file

@ -1,11 +1,11 @@
%{ %{
#include <sstream> #include <sstream>
#include<string.h> #include <string.h>
using namespace std;
#include "Assignment.h" #include "Assignment.h"
#include "expression.h" #include "expression.h"
#include "printutils.h" #include "printutils.h"
#include "value.h" #include "value.h"
#include "comment.h"
void yyerror(char *); void yyerror(char *);
int yylex(void); int yylex(void);
AssignmentList *argument; AssignmentList *argument;
@ -117,7 +117,7 @@ word:
} }
| word NUM | word NUM
{ {
string a; std::string a;
a=$1; a=$1;
a+=" "; a+=" ";
double dbl=$2; double dbl=$2;
@ -131,14 +131,14 @@ word:
double dbl=$1; double dbl=$1;
std::ostringstream strs; std::ostringstream strs;
strs<<dbl; strs<<dbl;
string a=" "; std::string a=" ";
a+=$2; a+=$2;
a=strs.str()+a; a=strs.str()+a;
$$=strdup(a.c_str()); $$=strdup(a.c_str());
} }
| word WORD | word WORD
{ {
string a; std::string a;
a=$1; a=$1;
a+=" "; a+=" ";
a+=$2; a+=$2;
@ -151,11 +151,10 @@ void yyerror(char *msg) {
argument=NULL; argument=NULL;
} }
AssignmentList * parser(const char *text) { AssignmentList *CommentParser::parser(const char *text)
{
yy_scan_string(text); yy_scan_string(text);
int parserretval = yyparse(); int parserretval = yyparse();
if (parserretval != 0) return NULL; if (parserretval != 0) return NULL;
return argument; return argument;
} }

View file

@ -1728,7 +1728,7 @@ void MainWindow::compileTopLevelDocument()
if (Feature::ExperimentalCustomizer.is_enabled()) { if (Feature::ExperimentalCustomizer.is_enabled()) {
if (this->root_module!=NULL) { if (this->root_module!=NULL) {
//add parameters as annotation in AST //add parameters as annotation in AST
addParameter(fulltext.c_str(),this->root_module); CommentParser::addParameter(fulltext.c_str(),this->root_module);
} }
this->parameterWidget->setParameters(this->root_module); this->parameterWidget->setParameters(this->root_module);
this->parameterWidget->applyParameters(this->root_module); this->parameterWidget->applyParameters(this->root_module);

View file

@ -404,7 +404,7 @@ int cmdline(const char *deps_output_file, const std::string &filename, Camera &c
if (Feature::ExperimentalCustomizer.is_enabled()) { if (Feature::ExperimentalCustomizer.is_enabled()) {
// add parameter to AST // add parameter to AST
addParameter(text.c_str(), root_module); CommentParser::addParameter(text.c_str(), root_module);
if (!parameterFile.empty() && !setName.empty()) { if (!parameterFile.empty() && !setName.empty()) {
ParameterSet param; ParameterSet param;
param.getParameterSet(parameterFile); param.getParameterSet(parameterFile);

View file

@ -36,7 +36,7 @@
#include <QInputDialog> #include <QInputDialog>
#include "modcontext.h" #include "modcontext.h"
extern AssignmentList * parser(const char *text); #include "comment.h"
ParameterWidget::ParameterWidget(QWidget *parent) : QWidget(parent) ParameterWidget::ParameterWidget(QWidget *parent) : QWidget(parent)
{ {
@ -304,7 +304,7 @@ void ParameterWidget::applyParameterSet(string setName){
}else{ }else{
AssignmentList *assignmentList; AssignmentList *assignmentList;
assignmentList=parser(v.second.data().c_str()); assignmentList=CommentParser::parser(v.second.data().c_str());
if(assignmentList==NULL){ if(assignmentList==NULL){
continue ; continue ;
} }

View file

@ -1,5 +1,6 @@
#include "parameterset.h" #include "parameterset.h"
#include "modcontext.h" #include "modcontext.h"
#include "comment.h"
ParameterSet::ParameterSet() ParameterSet::ParameterSet()
{ {
@ -70,7 +71,7 @@ void ParameterSet::applyParameterSet(FileModule *fileModule,string setName)
}else{ }else{
AssignmentList *assignmentList; AssignmentList *assignmentList;
assignmentList=parser(v.second.data().c_str()); assignmentList=CommentParser::parser(v.second.data().c_str());
if(assignmentList==NULL){ if(assignmentList==NULL){
continue ; continue ;
} }

View file

@ -1,10 +1,9 @@
#ifndef PARAMETERSET_H #ifndef PARAMETERSET_H
#define PARAMETERSET_H #define PARAMETERSET_H
#include"expression.h" #include "expression.h"
#include "FileModule.h" #include "FileModule.h"
#include "modcontext.h" #include "modcontext.h"
extern AssignmentList * parser(const char *text);
#include<map> #include<map>

View file

@ -1,7 +1,6 @@
#include "parametertext.h" #include "parametertext.h"
#include "modcontext.h" #include "modcontext.h"
extern AssignmentList * parser(const char *text); #include "comment.h"
ParameterText::ParameterText(ParameterObject *parameterobject, bool showDescription) ParameterText::ParameterText(ParameterObject *parameterobject, bool showDescription)
{ {
@ -26,7 +25,7 @@ void ParameterText::onChanged(QString)
else{ else{
ModuleContext ctx; ModuleContext ctx;
AssignmentList *assignmentList; AssignmentList *assignmentList;
assignmentList=parser(lineEdit->text().toStdString().c_str()); assignmentList=CommentParser::parser(lineEdit->text().toStdString().c_str());
if(assignmentList==NULL){ if(assignmentList==NULL){
return ; return ;
} }