Skip to content

Commit

Permalink
Fixed issue #80 and #83
Browse files Browse the repository at this point in the history
let user to specify whether it is for C, C++ or Fortran #80
Set two internal global variables for language: user_set_lang for storing user-specified language, auto_lang for storing parser detected language. And use setLang() to let user set the language.
  • Loading branch information
XinyaoYI committed Nov 22, 2019
1 parent 9bb30f3 commit 5c341ec
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 56 deletions.
7 changes: 4 additions & 3 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
#include <iostream>
#include <regex>

extern OpenMPDirective* parseOpenMP(const char*, void *_exprParse(const char*));

extern OpenMPDirective* parseOpenMP(const char*, void *_exprParse(const char*) , OpenMPBaseLang language);
extern void setLang(OpenMPBaseLang);
void output(OpenMPDirective*);
std::string test(OpenMPDirective*);
int openFile(std::ifstream&, const char*);
Expand Down Expand Up @@ -162,7 +162,8 @@ int main( int argc, const char* argv[] ) {


// example of calling ompparser without test file or producing DOT file.
const char* input = "omp target parallel for if(target:3456) if ( b)";
//setLang(Lang_C);
const char* input = "omp for linear(uval(a,b,c):2)";
OpenMPDirective* openMPAST = parseOpenMP(input, NULL);
output(openMPAST);

Expand Down
1 change: 0 additions & 1 deletion src/OpenMPIR.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ class OpenMPDirective : public SourceLocation {
* @return
*/
OpenMPClause * addOpenMPClause(OpenMPClauseKind kind, int * parameters);

/**
* normalize all the clause of a specific kind
* @param kind
Expand Down
131 changes: 79 additions & 52 deletions src/ompparser.yy
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,11 @@ void * (*exprParse)(const char*) = NULL;
bool b_within_variable_list = false; // a flag to indicate if the program is now processing a list of variables
int atomic_before_or_after = 0;

OpenMPBaseLang lang; //record language
/* used for language setting and detecting*/
OpenMPBaseLang user_set_lang = Lang_unknown;
OpenMPBaseLang auto_lang;
void setLang(OpenMPBaseLang _lang) { user_set_lang = _lang; };

%}

%locations
Expand Down Expand Up @@ -2109,10 +2113,10 @@ parallel_sections_directive : PARALLEL SECTIONS {
parallel_sections_clause_optseq
;
parallel_workshare_directive : PARALLEL WORKSHARE {
if(lang == Lang_Fortran)
{current_directive = new OpenMPDirective(OMPD_parallel_workshare);} else{
yyerror("parallel workshare is only supported in fortran");
YYABORT;
if (user_set_lang == Lang_Fortran || auto_lang == Lang_Fortran)
{current_directive = new OpenMPDirective(OMPD_parallel_workshare);} else{
yyerror("parallel workshare is only supported in fortran");
YYABORT;
}
}
parallel_workshare_clause_optseq
Expand Down Expand Up @@ -2177,7 +2181,7 @@ single_paired_directive : SINGLE {
single_paired_clause_optseq
;
workshare_directive : WORKSHARE {
if(lang == Lang_Fortran) {
if(user_set_lang == Lang_Fortran || auto_lang == Lang_Fortran) {
current_directive = new OpenMPDirective(OMPD_workshare);}
else{
yyerror("workshare is only supported in fortran");
Expand Down Expand Up @@ -2585,7 +2589,7 @@ for_clause : private_clause
do_clause : private_clause
| firstprivate_clause
| lastprivate_clause
| linear_clause_fortran
| linear_clause
| reduction_clause
| schedule_clause
| collapse_clause
Expand Down Expand Up @@ -2627,7 +2631,7 @@ for_simd_clause : if_simd_clause
do_simd_clause : if_simd_clause
| safelen_clause
| simdlen_clause
| linear_clause_fortran
| linear_clause
| aligned_clause
| private_clause
| firstprivate_clause
Expand Down Expand Up @@ -2722,7 +2726,7 @@ distribute_parallel_do_clause : if_parallel_clause
| proc_bind_clause
| allocate_clause
| lastprivate_clause
| linear_clause_fortran
| linear_clause
| schedule_clause
| collapse_clause
| ordered_clause
Expand Down Expand Up @@ -2763,7 +2767,7 @@ distribute_parallel_do_simd_clause : if_parallel_simd_clause
| proc_bind_clause
| allocate_clause
| lastprivate_clause
| linear_clause_fortran
| linear_clause
| schedule_clause
| collapse_clause
| ordered_clause
Expand Down Expand Up @@ -2803,7 +2807,7 @@ parallel_do_clause : if_parallel_clause
| proc_bind_clause
| allocate_clause
| lastprivate_clause
| linear_clause_fortran
| linear_clause
| schedule_clause
| collapse_clause
| ordered_clause
Expand Down Expand Up @@ -2976,8 +2980,8 @@ single_paired_clause : copyprivate_clause
;
construct_type_clause : PARALLEL { current_clause = current_directive->addOpenMPClause(OMPC_parallel); }
| SECTIONS { current_clause = current_directive->addOpenMPClause(OMPC_sections); }
| FOR { if(lang == Lang_C) {current_clause = current_directive->addOpenMPClause(OMPC_for);} else {yyerror("cancel or cancellation direcitve does not support for clause in fortran"); YYABORT; } }
| DO { if(lang == Lang_Fortran) {current_clause = current_directive->addOpenMPClause(OMPC_do);} else {yyerror("cancel or cancellation direcitve does not support DO clause in c"); YYABORT; } }
| FOR { if(user_set_lang != Lang_Fortran || auto_lang != Lang_Fortran) {current_clause = current_directive->addOpenMPClause(OMPC_for);} else {yyerror("cancel or cancellation direcitve does not support for clause in fortran"); YYABORT; } }
| DO { if(user_set_lang == Lang_Fortran || auto_lang == Lang_Fortran) {current_clause = current_directive->addOpenMPClause(OMPC_do);} else {yyerror("cancel or cancellation direcitve does not support DO clause in c"); YYABORT; } }
| TASKGROUP { current_clause = current_directive->addOpenMPClause(OMPC_taskgroup); }
;
//construct_type_clause_fortran : PARALLEL { current_clause = current_directive->addOpenMPClause(OMPC_parallel); }
Expand Down Expand Up @@ -3239,7 +3243,7 @@ copyprivate_clause : COPYPRIVATE {
}
;
fortran_copyprivate_clause : COPYPRIVATE {
if(lang == Lang_C) {current_clause = current_directive->addOpenMPClause(OMPC_copyprivate);} else {yyerror("Single does not support copyprivate_clause in Fortran."); YYABORT;}
if(user_set_lang == Lang_C || auto_lang == Lang_C) {current_clause = current_directive->addOpenMPClause(OMPC_copyprivate);} else {yyerror("Single does not support copyprivate_clause in Fortran."); YYABORT;}
} '(' var_list ')' {
}
;
Expand All @@ -3257,25 +3261,15 @@ linear_clause : LINEAR '(' linear_parameter ')'
| LINEAR '(' linear_parameter ':' EXPR_STRING { ((OpenMPLinearClause*)current_clause)->setUserDefinedStep($5); ((OpenMPLinearClause*)current_clause)->mergeLinear(current_directive, current_clause); } ')'
;

linear_clause_fortran : LINEAR '(' linear_parameter_fortran ')'
| LINEAR '(' linear_parameter_fortran ':' EXPR_STRING { ((OpenMPLinearClause*)current_clause)->setUserDefinedStep($5); } ')'
;
linear_parameter : EXPR_STRING { current_clause = current_directive->addOpenMPClause(OMPC_linear, OMPC_LINEAR_MODIFIER_unspecified); current_clause->addLangExpr($1); }
| EXPR_STRING ',' {current_clause = current_directive->addOpenMPClause(OMPC_linear, OMPC_LINEAR_MODIFIER_unspecified); current_clause->addLangExpr($1); } var_list
| EXPR_STRING ',' { current_clause = current_directive->addOpenMPClause(OMPC_linear, OMPC_LINEAR_MODIFIER_unspecified); current_clause->addLangExpr($1); } var_list
| linear_modifier '(' var_list ')'
;
linear_parameter_fortran : EXPR_STRING { current_clause = current_directive->addOpenMPClause(OMPC_linear, OMPC_LINEAR_MODIFIER_unspecified); current_clause->addLangExpr($1); }
| EXPR_STRING ',' {current_clause = current_directive->addOpenMPClause(OMPC_linear, OMPC_LINEAR_MODIFIER_unspecified); current_clause->addLangExpr($1); } var_list
| linear_modifier_fortran '(' var_list ')'
;
linear_modifier : MODOFIER_VAL { current_clause = current_directive->addOpenMPClause(OMPC_linear,OMPC_LINEAR_MODIFIER_val); }
| MODOFIER_REF { if (user_set_lang == Lang_unknown && auto_lang == Lang_C){ auto_lang = Lang_Cplusplus; } if (user_set_lang == Lang_C) {yyerror("REF modifier is not supportted in C."); YYABORT; } else { current_clause = current_directive->addOpenMPClause(OMPC_linear, OMPC_LINEAR_MODIFIER_ref); } }
| MODOFIER_UVAL { if (user_set_lang == Lang_unknown && auto_lang == Lang_C){ auto_lang = Lang_Cplusplus; } if (user_set_lang == Lang_C) {yyerror("UVAL modifier is not supportted in C."); YYABORT;} else { current_clause = current_directive->addOpenMPClause(OMPC_linear, OMPC_LINEAR_MODIFIER_uval); } }
;

linear_modifier_fortran : MODOFIER_VAL { current_clause = current_directive->addOpenMPClause(OMPC_linear,OMPC_LINEAR_MODIFIER_val); }
| MODOFIER_REF { current_clause = current_directive->addOpenMPClause(OMPC_linear,OMPC_LINEAR_MODIFIER_ref); }
| MODOFIER_UVAL { current_clause = current_directive->addOpenMPClause(OMPC_linear,OMPC_LINEAR_MODIFIER_uval); }
;

aligned_clause : ALIGNED '(' aligned_parameter ')'
| ALIGNED '(' aligned_parameter ':' EXPR_STRING { ((OpenMPAlignedClause*)current_clause)->setUserDefinedAlignment($5);} ')'
;
Expand Down Expand Up @@ -3310,7 +3304,7 @@ collapse_clause: COLLAPSE { current_clause = current_directive->addOpenMPClause(
ordered_clause: ORDERED { current_clause = current_directive->addOpenMPClause(OMPC_ordered); } '(' expression ')'
| ORDERED { current_clause = current_directive->addOpenMPClause(OMPC_ordered); }
;
fortran_nowait_clause: NOWAIT { if(lang == Lang_C) {current_clause = current_directive->addOpenMPClause(OMPC_nowait);} else {yyerror("Sections does not support nowait clause in Fortran."); YYABORT;} }
fortran_nowait_clause: NOWAIT { if(user_set_lang == Lang_C || auto_lang == Lang_C) {current_clause = current_directive->addOpenMPClause(OMPC_nowait);} else {yyerror("Sections does not support nowait clause in Fortran."); YYABORT;} }
;
nowait_clause: NOWAIT { current_clause = current_directive->addOpenMPClause(OMPC_nowait); }
;
Expand Down Expand Up @@ -3438,28 +3432,61 @@ int yywrap()
OpenMPDirective* parseOpenMP(const char* _input, void * _exprParse(const char*)) {
printf("Start parsing...\n");
OpenMPBaseLang base_lang = Lang_C;
lang = Lang_C;
exprParse = _exprParse;
current_directive = NULL;
std::string input_string;
const char *input = _input;
// Since we can't guarantee the input has been preprocessed, it should be checked here.
std::regex fortran_regex ("[!][$][Oo][Mm][Pp]");
input_string = std::string(input, 5);
if (std::regex_match(input_string, fortran_regex)) {
base_lang = Lang_Fortran;
lang = Lang_Fortran;
input_string = std::string(input);
std::transform(input_string.begin(), input_string.end(), input_string.begin(), ::tolower);
input = input_string.c_str();
};
//depend_iterators_definition_class = new std::vector<std::vector<const char*>* >();
start_lexer(input);
int res = yyparse();
//depend_iterators_definition_class.clear();
end_lexer();
if (current_directive) {
current_directive->setBaseLang(base_lang);
};
return current_directive;
if (user_set_lang == Lang_unknown){
auto_lang = Lang_C;
exprParse = _exprParse;
current_directive = NULL;
std::string input_string;
const char *input = _input;
// Since we can't guarantee the input has been preprocessed, it should be checked here.
std::regex fortran_regex ("[!][$][Oo][Mm][Pp]");
input_string = std::string(input, 5);
if (std::regex_match(input_string, fortran_regex)) {
base_lang = Lang_Fortran;
auto_lang = Lang_Fortran;
input_string = std::string(input);
std::transform(input_string.begin(), input_string.end(), input_string.begin(), ::tolower);
input = input_string.c_str();
};
//depend_iterators_definition_class = new std::vector<std::vector<const char*>* >();
start_lexer(input);
int res = yyparse();
//depend_iterators_definition_class.clear();
end_lexer();
if (current_directive) {
current_directive->setBaseLang(base_lang);
};
return current_directive;
} else {
OpenMPBaseLang base_lang = user_set_lang;
exprParse = _exprParse;
current_directive = NULL;
std::string input_string;
const char *input = _input;

// Since we can't guarantee the input has been preprocessed, it should be checked here.
std::regex fortran_regex ("[!][$][Oo][Mm][Pp]");
input_string = std::string(input, 5);
if (std::regex_match(input_string, fortran_regex)) {
if(user_set_lang != Lang_Fortran){
yyerror("You specify the language is C/C++, but you are processing Fortran");
return 0;
}
};
// Since we can't guarantee the input has been preprocessed, it should be checked here.
if (!std::regex_match(input_string, fortran_regex)) {
if(user_set_lang == Lang_Fortran){
yyerror("You specify the language Fortran, but you are processing C/C++");
return 0;
}
};

start_lexer(input);
int res = yyparse();
end_lexer();
if (current_directive) {
current_directive->setBaseLang(base_lang);
};
return current_directive;
}
}

0 comments on commit 5c341ec

Please sign in to comment.