diff options
Diffstat (limited to 'src/parse_file.c')
-rw-r--r-- | src/parse_file.c | 717 |
1 files changed, 619 insertions, 98 deletions
diff --git a/src/parse_file.c b/src/parse_file.c index ae3a9af..e998803 100644 --- a/src/parse_file.c +++ b/src/parse_file.c @@ -1,5 +1,5 @@ /* -Copyright 2015 Ian Jauslin +Copyright 2015-2022 Ian Jauslin Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -30,6 +30,8 @@ limitations under the License. #include "istring.h" #include "tools.h" #include "idtable.h" +#include "tree.h" +#include "symbolic_parser.h" // parsing modes @@ -59,6 +61,70 @@ limitations under the License. #define PP_GROUP_MODE 16 +// read a positive integer from a string +int read_positive_int(char* str, int* out){ + char* ptr; + int res; + for(ptr=str;*ptr!='\0';ptr++){ + if(*ptr-'0'>=10 || *ptr-'0'<0){ + return(-1); + } + } + res=sscanf(str,"%d",out); + if(res!=1){ + return(-2); + } + return(0); +} +// read an integer from a string +int read_int(char* str, int* out){ + char* ptr; + int res; + for(ptr=str;*ptr!='\0';ptr++){ + if((*ptr-'0'>=10 || *ptr-'0'<0) && (*ptr!='-')){ + return(-1); + } + } + res=sscanf(str,"%d",out); + if(res!=1){ + return(-2); + } + return(0); +} +// read an long int from a string +int read_long_int(char* str, long int* out){ + char* ptr; + int res; + for(ptr=str;*ptr!='\0';ptr++){ + if((*ptr-'0'>=10 || *ptr-'0'<0) && (*ptr!='-')){ + return(-1); + } + } + res=sscanf(str,"%ld",out); + if(res!=1){ + return(-2); + } + return(0); +} + +// read a long double +int read_long_double(char* str, long double* out){ + char* ptr; + int res; + for(ptr=str;*ptr!='\0';ptr++){ + if((*ptr-'0'>=10 || *ptr-'0'<0) && (*ptr!='-') && (*ptr!='e') && (*ptr!='E') && (*ptr!='.')){ + return(-1); + } + } + res=sscanf(str,"%Lf",out); + if(res!=1){ + return(-2); + } + return(0); +} + + + // parse fields list int parse_input_fields(Char_Array str_fields, Fields_Table* fields){ // buffer @@ -67,6 +133,8 @@ int parse_input_fields(Char_Array str_fields, Fields_Table* fields){ int i,j; int mode; int comment=0; + int res; + int expect_colon=0; // allocate memory init_Fields_Table(fields); @@ -86,39 +154,100 @@ int parse_input_fields(Char_Array str_fields, Fields_Table* fields){ if(mode==PP_NULL_MODE){ mode=PP_PARAMETER_MODE; } + else{ + fprintf(stderr,"syntax error: fields entry (%d): 'h' should be at the beginning of the line\n",j); + exit(-1); + } + // flag: colon is expected immediately after letter + expect_colon=1; break; // external fields case 'x': if(mode==PP_NULL_MODE){ mode=PP_EXTERNAL_MODE; } + else{ + fprintf(stderr,"syntax error: fields entry (%d): 'x' should be at the beginning of the line\n",j); + exit(-1); + } + // flag: colon is expected immediately after letter + expect_colon=1; break; // internal fields case 'i': if(mode==PP_NULL_MODE){ mode=PP_INTERNAL_MODE; } + else{ + fprintf(stderr,"syntax error: fields entry (%d): 'i' should be at the beginning of the line\n",j); + exit(-1); + } + // flag: colon is expected immediately after letter + expect_colon=1; break; case 'f': if(mode==PP_NULL_MODE){ mode=PP_FERMIONS_MODE; } + else{ + fprintf(stderr,"syntax error: fields entry (%d): 'f' should be at the beginning of the line\n",j); + exit(-1); + } + // flag: colon is expected immediately after letter + expect_colon=1; break; case 'a': if(mode==PP_NULL_MODE){ mode=PP_NONCOMMUTING_MODE; } + else{ + fprintf(stderr,"syntax error: fields entry (%d): 'a' should be at the beginning of the line\n",j); + exit(-1); + } + // flag: colon is expected immediately after letter + expect_colon=1; break; // reset buffer case ':': + // check mode + if(mode==PP_NULL_MODE || expect_colon==0){ + fprintf(stderr,"syntax error: fields entry (%d): ':' must be preceded by 'h', 'x', 'i', 'f', or 'a' on the same line\n",j); + exit(-1); + } + expect_colon=0; buffer_ptr=buffer; *buffer_ptr='\0'; break; // write to fields case ',': - sscanf(buffer,"%d",&i); + res=read_positive_int(buffer,&i); + + // check i + if(res<0){ + fprintf(stderr,"syntax error: fields entry (%d): fields must be non-negative integers, got '%s'\n",j,buffer); + exit(-1); + } + if(mode==PP_PARAMETER_MODE || mode==PP_EXTERNAL_MODE || mode==PP_INTERNAL_MODE){ + if(int_array_find(i,fields->parameter)>=0 || int_array_find(i,fields->external)>=0 || int_array_find(i,fields->internal)>=0){ + fprintf(stderr,"error: fields entry (%d): field %d is already present in the fields table\n",j,i); + exit(-1); + } + } + else if(mode==PP_FERMIONS_MODE){ + if(int_array_find(i,fields->fermions)>=0){ + fprintf(stderr,"error: fields entry (%d): field %d is already present in the Fermions table\n",j,i); + exit(-1); + } + } + else if(mode==PP_NONCOMMUTING_MODE){ + if(int_array_find(i,fields->noncommuting)>=0){ + fprintf(stderr,"error: fields entry (%d): field %d is already present in the noncommuting table\n",j,i); + exit(-1); + } + } + if(mode==PP_PARAMETER_MODE){ int_array_append(i,&((*fields).parameter)); } @@ -134,31 +263,65 @@ int parse_input_fields(Char_Array str_fields, Fields_Table* fields){ else if(mode==PP_NONCOMMUTING_MODE){ int_array_append(i,&((*fields).noncommuting)); } + else{ + fprintf(stderr,"syntax error: fields entry (%d): misplaced ','\n",j); + exit(-1); + } buffer_ptr=buffer; *buffer_ptr='\0'; break; // back to null mode case '\n': - sscanf(buffer,"%d",&i); - if(mode==PP_PARAMETER_MODE){ - int_array_append(i,&((*fields).parameter)); - } - else if(mode==PP_EXTERNAL_MODE){ - int_array_append(i,&((*fields).external)); - } - else if(mode==PP_INTERNAL_MODE){ - int_array_append(i,&((*fields).internal)); - } - else if(mode==PP_FERMIONS_MODE){ - int_array_append(i,&((*fields).fermions)); - } - else if(mode==PP_NONCOMMUTING_MODE){ - int_array_append(i,&((*fields).noncommuting)); + // ignore if in NULL_MODE + if(mode!=PP_NULL_MODE){ + res=read_positive_int(buffer,&i); + // check i + if(res<0){ + fprintf(stderr,"syntax error: fields entry (%d): fields must be non-negative integers, got '%s'\n",j,buffer); + exit(-1); + } + if(mode==PP_PARAMETER_MODE || mode==PP_EXTERNAL_MODE || mode==PP_INTERNAL_MODE){ + if(int_array_find(i,fields->parameter)>=0 || int_array_find(i,fields->external)>=0 || int_array_find(i,fields->internal)>=0){ + fprintf(stderr,"error: fields entry (%d): field %d is already present in the fields table\n",j,i); + exit(-1); + } + } + else if(mode==PP_FERMIONS_MODE){ + if(int_array_find(i,fields->fermions)>=0){ + fprintf(stderr,"error: fields entry (%d): field %d is already present in the Fermions table\n",j,i); + exit(-1); + } + } + else if(mode==PP_NONCOMMUTING_MODE){ + if(int_array_find(i,fields->noncommuting)>=0){ + fprintf(stderr,"error: fields entry (%d): field %d is already present in the noncommuting table\n",j,i); + exit(-1); + } + } + + if(mode==PP_PARAMETER_MODE){ + int_array_append(i,&((*fields).parameter)); + } + else if(mode==PP_EXTERNAL_MODE){ + int_array_append(i,&((*fields).external)); + } + else if(mode==PP_INTERNAL_MODE){ + int_array_append(i,&((*fields).internal)); + } + else if(mode==PP_FERMIONS_MODE){ + int_array_append(i,&((*fields).fermions)); + } + else if(mode==PP_NONCOMMUTING_MODE){ + int_array_append(i,&((*fields).noncommuting)); + } + mode=PP_NULL_MODE; } - mode=PP_NULL_MODE; break; + + // ignore spaces + case ' ':break; // comment case '#': comment=1; @@ -168,57 +331,85 @@ int parse_input_fields(Char_Array str_fields, Fields_Table* fields){ if(mode!=PP_NULL_MODE){ buffer_ptr=str_addchar(buffer_ptr,str_fields.str[j]); } + else{ + fprintf(stderr,"syntax error: fields entry (%d): unrecognized character '%c'\n",j,str_fields.str[j]); + exit(-1); + } + break; + break; } } } free(buffer); + + // check whether there are non-Fermionic internal fields + for(i=0;i<(*fields).internal.length;i++){ + if(is_fermion((*fields).internal.values[i], *fields)==0){ + fprintf(stderr,"warning: some internal fields are not Fermions: means may be computed using sums over permutations rather than the more efficient LU decomposition\n"); + break; + } + } + return(0); } -// parse symbols list +// parse virtual_fields list // write result to fields -int parse_input_symbols(Char_Array str_symbols, Fields_Table* fields){ +int parse_input_virtual_fields(Char_Array str_virtual_fields, Fields_Table* fields, Variables variables){ // buffer - char* buffer=calloc(str_symbols.length+1,sizeof(char)); + char* buffer=calloc(str_virtual_fields.length+1,sizeof(char)); char* buffer_ptr=buffer; Polynomial polynomial; int index; int i,j; int mode; int comment=0; + int res; // loop over input mode=PP_INDEX_MODE; - for(j=0;j<str_symbols.length;j++){ + for(j=0;j<str_virtual_fields.length;j++){ if(comment==1){ - if(str_symbols.str[j]=='\n'){ + if(str_virtual_fields.str[j]=='\n'){ comment=0; } } // stay in polynomial mode until ',' else if(mode==PP_POLYNOMIAL_MODE){ - if(str_symbols.str[j]==','){ + if(str_virtual_fields.str[j]==','){ // parse polynomial - str_to_Polynomial(buffer, &polynomial); + parse_symbolic_expression_str(buffer, *fields, variables, &polynomial); // write index and polynomial - symbols_append_noinit(index, polynomial, &((*fields).symbols)); + virtual_fields_append_noinit(index, polynomial, &((*fields).virtual_fields)); mode=PP_INDEX_MODE; buffer_ptr=buffer; *buffer_ptr='\0'; } + // check there are no '=' signs in polynomial (forgotten ',') + else if(str_virtual_fields.str[j]=='='){ + fprintf(stderr,"syntax error: virtual fields entry (%d): '=' in polynomial '%s'\n",j, buffer); + exit(-1); + } + else if(str_virtual_fields.str[j]=='#'){ + comment=1; + } else{ - buffer_ptr=str_addchar(buffer_ptr,str_symbols.str[j]); + buffer_ptr=str_addchar(buffer_ptr,str_virtual_fields.str[j]); } } else{ - switch(str_symbols.str[j]){ + switch(str_virtual_fields.str[j]){ // polynomial mode case '=': if(mode==PP_INDEX_MODE){ // read index - sscanf(buffer,"%d",&index); + res=read_positive_int(buffer, &index); + if(res<0){ + fprintf(stderr,"syntax error: virtual fields entry (%d): virtual field index must be a non-negative integer, got '%s'\n",j,buffer); + exit(-1); + } // reset buffer buffer_ptr=buffer; *buffer_ptr='\0'; @@ -226,43 +417,53 @@ int parse_input_symbols(Char_Array str_symbols, Fields_Table* fields){ } break; + // misplaced ',' + case ',': + fprintf(stderr,"syntax error: virtual fields entry (%d): misplaced ',' or forgotten virtual field index\n",j); + exit(-1); + break; + + // ignore spaces and newlines + case ' ':break; + case '\n':break; + // comment case '#': comment=1; break; default: - buffer_ptr=str_addchar(buffer_ptr,str_symbols.str[j]); + buffer_ptr=str_addchar(buffer_ptr,str_virtual_fields.str[j]); break; } } } // last step - if(polynomial.length>0){ - str_to_Polynomial(buffer, &polynomial); - symbols_append_noinit(index, polynomial, &((*fields).symbols)); - } + parse_symbolic_expression_str(buffer, *fields, variables, &polynomial); + virtual_fields_append_noinit(index, polynomial, &((*fields).virtual_fields)); // simplify - for(i=0;i<(*fields).symbols.length;i++){ - polynomial_simplify((*fields).symbols.expr+i, *fields); + for(i=0;i<(*fields).virtual_fields.length;i++){ + polynomial_simplify((*fields).virtual_fields.expr+i, *fields); } free(buffer); return(0); } + // parse groups of independent fields -int parse_input_groups(Char_Array str_groups, Groups* groups){ +int parse_input_groups(Char_Array str_groups, Groups* groups, Polynomial_Matrix propagator, Fields_Table fields){ // buffer char* buffer=calloc(str_groups.length+1,sizeof(char)); char* buffer_ptr=buffer; int index; - int j; + int i,j; Int_Array group; int mode; int comment=0; + int res; // alloc init_Groups(groups, GROUP_SIZE); @@ -287,26 +488,60 @@ int parse_input_groups(Char_Array str_groups, Groups* groups){ init_Int_Array(&group, GROUP_SIZE); mode=PP_GROUP_MODE; } + else{ + fprintf(stderr,"syntax error: groups entry (%d): nested parentheses are not allowed in this entry\n",j); + exit(-1); + } break; case')': if(mode==PP_GROUP_MODE){ - sscanf(buffer,"%d",&index); + res=read_positive_int(buffer,&index); + if(res<0){ + fprintf(stderr,"syntax error: groups entry (%d): index must be a non-negative integer, got '%s'\n",j,buffer); + exit(-1); + } + for(i=0;i<groups->length;i++){ + if(int_array_find(index,groups->indices[i])>=0){ + fprintf(stderr,"syntax error: groups entry (%d): index %d is already present in group %d\n",j,index,i); + exit(-1); + } + } + int_array_append(index, &group); groups_append_noinit(group, groups); mode=PP_NULL_MODE; } + else{ + fprintf(stderr,"syntax error: groups entry (%d): extra ')'\n",j); + exit(-1); + } break; // read index case',': if(mode==PP_GROUP_MODE){ - sscanf(buffer,"%d",&index); + res=read_positive_int(buffer,&index); + if(res<0){ + fprintf(stderr,"syntax errorL groups entry (%d): index must be a non-negative integer, got '%s'\n",j,buffer); + exit(-1); + } + for(i=0;i<groups->length;i++){ + if(int_array_find(index,groups->indices[i])>=0){ + fprintf(stderr,"syntax error: groups entry (%d): index %d is already present in group %d\n",j,index,i); + exit(-1); + } + } + int_array_append(index, &group); buffer_ptr=buffer; *buffer_ptr='\0'; } break; + // skip spaces and newlines + case ' ':break; + case '\n':break; + // comment case '#': comment=1; @@ -316,11 +551,204 @@ int parse_input_groups(Char_Array str_groups, Groups* groups){ if(mode!=PP_NULL_MODE){ buffer_ptr=str_addchar(buffer_ptr,str_groups.str[j]); } + else{ + fprintf(stderr,"syntax error: groups entry (%d): unrecognized character '%c'\n",j,str_groups.str[j]); + exit(-1); + } + break; + } + } + } + + // check fields in groups + check_groups(*groups, propagator, fields); + + free(buffer); + return(0); +} + +// check that the members of groups are independent (assuming the virtual fields and propagator were already parsed) +int check_groups(Groups groups, Polynomial_Matrix propagator, Fields_Table fields){ + Int_Array* group_fields=calloc(groups.length,sizeof(Int_Array)); + int i,j,k,l,a,b; + + // get the lists of fields involved in each group + for(i=0;i<groups.length;i++){ + // expand virtual_fields + fields_in_virtual_field_list(groups.indices[i], fields, group_fields+i); + } + + // check whether pairs of fields are present in the propagator + for(i=0;i<groups.length;i++){ + for(j=0;j<group_fields[i].length;j++){ + if(field_type(group_fields[i].values[j], fields)==FIELD_INTERNAL){ + for(k=0;k<groups.length;k++){ + if(k!=i){ + for(l=0;l<group_fields[k].length;l++){ + if(field_type(group_fields[k].values[l], fields)==FIELD_INTERNAL){ + if(group_fields[i].values[j]==group_fields[k].values[l]){ + fprintf(stderr,"error: groups %d and %d both contain internal field %d\n",i,k,group_fields[i].values[j]); + exit(-1); + } + a=intlist_find(propagator.indices, propagator.length, group_fields[i].values[j]); + b=intlist_find(propagator.indices, propagator.length, group_fields[k].values[l]); + if(a>=0 && b>=0 && polynomial_is_zero(propagator.matrix[a][b])==0){ + fprintf(stderr,"error: groups %d and %d are not independent: they contain %d and %d which have a non-vanishing propagator\n",i,k,group_fields[i].values[j], group_fields[k].values[l]); + exit(-1); + } + } + } + } + } + } + } + } + + for(i=0;i<groups.length;i++){ + free_Int_Array(group_fields[i]); + } + free(group_fields); + + return(0); +} + +// list of fields involved in a list of virtual_fields +int fields_in_virtual_field_list(Int_Array indices, Fields_Table fields, Int_Array* output){ + int i,j,k; + Int_Array tmp_array; + + init_Int_Array(output,FIELDS_SIZE); + for(k=0;k<indices.length;k++){ + if(field_type(indices.values[k],fields)!=FIELD_VIRTUAL){ + int_array_append(abs(indices.values[k]), output); + } + else{ + i=intlist_find_err(fields.virtual_fields.indices, fields.virtual_fields.length, indices.values[k]); + for(j=0;j<fields.virtual_fields.expr[i].length;j++){ + fields_in_virtual_field_list(fields.virtual_fields.expr[i].monomials[j], fields, &tmp_array); + int_array_concat_unique(tmp_array, output); + free_Int_Array(tmp_array); + } + } + } + + return(0); +} + + + +// parse variables list +int parse_input_variables(Char_Array str_variables, Variables* variables){ + // buffer + char* buffer=calloc(str_variables.length+1,sizeof(char)); + char* buffer_ptr=buffer; + Tree symbol_tree; + Char_Array varname; + int j; + int mode; + int comment=0; + char* ptr; + + init_Variables(variables,VARIABLES_SIZE); + + // loop over input + mode=PP_INDEX_MODE; + for(j=0;j<str_variables.length;j++){ + if(comment==1){ + if(str_variables.str[j]=='\n'){ + comment=0; + } + } + // stay in polynomial mode until ',' + else if(mode==PP_POLYNOMIAL_MODE){ + if(str_variables.str[j]==','){ + // parse symbol tree + str_to_symbol_tree(buffer, &symbol_tree); + variables_append_noinit(varname , symbol_tree, variables); + mode=PP_INDEX_MODE; + buffer_ptr=buffer; + *buffer_ptr='\0'; + } + // check there are no '=' signs in polynomial (forgotten ',') + else if(str_variables.str[j]=='='){ + fprintf(stderr,"syntax error: preprocessor_variables entry (%d): '=' in polynomial '%s'\n",j, buffer); + exit(-1); + } + else if(str_variables.str[j]=='#'){ + comment=1; + } + else{ + buffer_ptr=str_addchar(buffer_ptr,str_variables.str[j]); + } + } + else{ + switch(str_variables.str[j]){ + // polynomial mode + case '=': + if(mode==PP_INDEX_MODE){ + if(*buffer=='\0'){ + fprintf(stderr,"syntax error: preprocessor_variables entry (%d): empty variable name\n",j); + exit(-1); + } + for(ptr=buffer;*ptr!='\0';ptr++){ + if(*ptr=='<' || *ptr=='>'){ + fprintf(stderr,"syntax error: preprocessor_variables entry (%d): forbidden '%c' character in variable name '%s'\n",j,*ptr,buffer); + exit(-1); + } + } + str_to_char_array(buffer,&varname); + // check that the variable name is not 'OUT' or 'FLOW' or 'RCC' + if(char_array_cmp_str(varname, "OUT")==1){ + fprintf(stderr,"error: preprocessor_variables entry (%d): variable name cannot be 'OUT' (this name is reserved)\n",j); + exit(-1); + } + if(char_array_cmp_str(varname, "FLOW")==1){ + fprintf(stderr,"error: preprocessor_variables entry (%d): variable name cannot be 'FLOW' (this name is reserved)\n",j); + exit(-1); + } + if(char_array_cmp_str(varname, "RCC")==1){ + fprintf(stderr,"error: preprocessor_variables entry (%d): variable name cannot be 'RCC' (this name is reserved)\n",j); + exit(-1); + } + // reset buffer + buffer_ptr=buffer; + *buffer_ptr='\0'; + mode=PP_POLYNOMIAL_MODE; + } + break; + + // misplaced ',' + case ',': + fprintf(stderr,"syntax error: preprocessor_variables entry (%d): misplaced ',' or forgotten variable name\n",j); + exit(-1); + break; + + // ignore characters + case ' ':break; + case '\n': break; + + // comment + case '#': + comment=1; + break; + + default: + buffer_ptr=str_addchar(buffer_ptr,str_variables.str[j]); break; } } } + // last step + if(mode==PP_POLYNOMIAL_MODE){ + str_to_symbol_tree(buffer, &symbol_tree); + variables_append_noinit(varname , symbol_tree, variables); + } + else if(*buffer!='\0'){ + fprintf(stderr,"syntax error: preprocessor_variables entry (%d): mismatched variable/polynomial pair, got '%s'\n",j,buffer); + exit(-1); + } + free(buffer); return(0); } @@ -328,7 +756,7 @@ int parse_input_groups(Char_Array str_groups, Groups* groups){ // parse identities between fields // write result to fields -int parse_input_identities(Char_Array str_identities, Fields_Table* fields){ +int parse_input_identities(Char_Array str_identities, Fields_Table* fields, Variables variables){ // buffer char* buffer=calloc(str_identities.length+1,sizeof(char)); char* buffer_ptr=buffer; @@ -339,6 +767,7 @@ int parse_input_identities(Char_Array str_identities, Fields_Table* fields){ int tmp; int mode; int comment=0; + int ret; init_Int_Array(&monomial, MONOMIAL_SIZE); @@ -354,13 +783,21 @@ int parse_input_identities(Char_Array str_identities, Fields_Table* fields){ else if(mode==PP_POLYNOMIAL_MODE){ if(str_identities.str[j]==','){ // parse polynomial - str_to_Polynomial(buffer, &polynomial); + parse_symbolic_expression_str(buffer, *fields, variables, &polynomial); // write monomial and polynomial identities_append_noinit(monomial, polynomial, &((*fields).ids)); // realloc init_Int_Array(&monomial, MONOMIAL_SIZE); mode=PP_NULL_MODE; } + // check there are no '=' signs in polynomial (forgotten ',') + else if(str_identities.str[j]=='='){ + fprintf(stderr,"syntax error: identities entry (%d): '=' in polynomial '%s'\n",j, buffer); + exit(-1); + } + else if(str_identities.str[j]=='#'){ + comment=1; + } else{ buffer_ptr=str_addchar(buffer_ptr,str_identities.str[j]); } @@ -377,20 +814,36 @@ int parse_input_identities(Char_Array str_identities, Fields_Table* fields){ buffer_ptr=buffer; *buffer_ptr='\0'; } + else{ + fprintf(stderr,"syntax error: identities entry (%d): misplaced '['\n",j); + exit(-1); + } break; // for notational homogeneity case 'f': if(mode==PP_BRACKET_MODE){ mode=PP_FIELD_MODE; } + else{ + fprintf(stderr,"syntax error: identities entry (%d): misplaced 'f'\n",j); + exit(-1); + } break; // write monomial term case ']': if(mode==PP_FIELD_MODE){ - sscanf(buffer,"%d",&i); + ret=read_int(buffer,&i); + if(ret<0){ + fprintf(stderr,"syntax error: identities entry (%d): field indices must be integers, got '%s'\n",j,buffer); + exit(-1); + } int_array_append(i,&monomial); mode=PP_INDEX_MODE; } + else{ + fprintf(stderr,"syntax error: identities entry (%d): mismatched ']'\n",j); + exit(-1); + } break; // polynomial mode @@ -400,8 +853,22 @@ int parse_input_identities(Char_Array str_identities, Fields_Table* fields){ *buffer_ptr='\0'; mode=PP_POLYNOMIAL_MODE; } + else{ + fprintf(stderr,"syntax error: identities entry (%d): misplaced '='\n",j); + exit(-1); + } break; + // misplaced ',' + case ',': + fprintf(stderr,"syntax error: identities entry (%d): misplaced ',' or forgotten left hand side\n",j); + exit(-1); + break; + + // ignore spaces and newlines + case ' ':break; + case '\n':break; + // comment case '#': comment=1; @@ -411,6 +878,10 @@ int parse_input_identities(Char_Array str_identities, Fields_Table* fields){ if(mode!=PP_NULL_MODE){ buffer_ptr=str_addchar(buffer_ptr,str_identities.str[j]); } + else{ + fprintf(stderr,"syntax error: identities entry (%d): unrecognized character '%c'\n",j,str_identities.str[j]); + exit(-1); + } break; } } @@ -418,9 +889,13 @@ int parse_input_identities(Char_Array str_identities, Fields_Table* fields){ // last step if(mode==PP_POLYNOMIAL_MODE){ - str_to_Polynomial(buffer, &polynomial); + parse_symbolic_expression_str(buffer, *fields, variables, &polynomial); identities_append_noinit(monomial, polynomial, &((*fields).ids)); } + else if(*buffer!='\0'){ + fprintf(stderr,"syntax error: identities entry (%d): mismatched left/right hand side, got '%s'\n",j,buffer); + exit(-1); + } else{ free_Int_Array(monomial); } @@ -451,6 +926,7 @@ int parse_input_propagator(Char_Array str_propagator, Polynomial_Matrix* propaga int index2=-1; int mode; int comment=0; + int ret; // allocate memory init_Polynomial_Matrix(propagator, fields.internal.length); @@ -473,20 +949,36 @@ int parse_input_propagator(Char_Array str_propagator, Polynomial_Matrix* propaga // indices case ';': if(mode==PP_INDEX_MODE){ - sscanf(buffer,"%d",&i); + ret=read_positive_int(buffer,&i); + if(ret<0){ + fprintf(stderr,"syntax error: propagator entry (%d): indices must be non-negative integers, got '%s'\n",j,buffer); + exit(-1); + } index1=intlist_find_err((*propagator).indices, (*propagator).length, i); buffer_ptr=buffer; *buffer_ptr='\0'; } + else{ + fprintf(stderr,"syntax error: propagator entry (%d): misplaced ';'\n",j); + exit(-1); + } break; case ':': if(mode==PP_INDEX_MODE){ - sscanf(buffer,"%d",&i); + ret=read_positive_int(buffer,&i); + if(ret<0){ + fprintf(stderr,"syntax error: propagator entry (%d): indices must be non-negative integers, got '%s'\n",j,buffer); + exit(-1); + } index2=intlist_find_err((*propagator).indices, (*propagator).length, i); buffer_ptr=buffer; *buffer_ptr='\0'; mode=PP_POLYNOMIAL_MODE; } + else{ + fprintf(stderr,"syntax error: propagator entry (%d): misplaced ':'\n",j); + exit(-1); + } break; // num @@ -494,12 +986,22 @@ int parse_input_propagator(Char_Array str_propagator, Polynomial_Matrix* propaga if(mode==PP_POLYNOMIAL_MODE && index1>=0 && index2>=0){ free_Polynomial((*propagator).matrix[index1][index2]); str_to_Polynomial(buffer,(*propagator).matrix[index1]+index2); + index1=-1; + index2=-1; buffer_ptr=buffer; *buffer_ptr='\0'; mode=PP_INDEX_MODE; } + else{ + fprintf(stderr,"syntax error: propagator entry (%d): mismatched index/polynomial pair\n",j); + exit(-1); + } break; + // ignore ' 'and newline + case ' ':break; + case '\n':break; + // comment case '#': comment=1; @@ -517,6 +1019,15 @@ int parse_input_propagator(Char_Array str_propagator, Polynomial_Matrix* propaga free_Polynomial((*propagator).matrix[index1][index2]); str_to_Polynomial(buffer,(*propagator).matrix[index1]+index2); } + else if (*buffer!='\0'){ + fprintf(stderr,"syntax error: propagator entry (%d): mismatched index/polynomial pair, got '%s'\n",j,buffer); + exit(-1); + } + + // check whether the polynomial is numeric + if(polynomial_matrix_is_numeric(*propagator)==0){ + fprintf(stderr,"warning: the propagator contains polynomial entries: means may be computed using sums over permutations rather than the more efficient LU decomposition\n"); + } free(buffer); return(0); @@ -524,49 +1035,9 @@ int parse_input_propagator(Char_Array str_propagator, Polynomial_Matrix* propaga // parse input polynomial -int parse_input_polynomial(Char_Array str_polynomial, Polynomial* output, Fields_Table fields){ - int j; - // buffer - char* buffer=calloc(str_polynomial.length+1,sizeof(char)); - char* buffer_ptr=buffer; - Polynomial tmp_poly; - - // allocate memory - init_Polynomial(output,POLY_SIZE); - - for(j=0;j<str_polynomial.length;j++){ - switch(str_polynomial.str[j]){ - case '*': - str_to_Polynomial(buffer, &tmp_poly); - if((*output).length==0){ - polynomial_concat(tmp_poly, output); - } - else{ - polynomial_prod_chain(tmp_poly, output, fields); - } - free_Polynomial(tmp_poly); - - buffer_ptr=buffer; - *buffer_ptr='\0'; - break; - - default: - buffer_ptr=str_addchar(buffer_ptr,str_polynomial.str[j]); - break; - } - } - - //last step - str_to_Polynomial(buffer, &tmp_poly); - if((*output).length==0){ - polynomial_concat(tmp_poly, output); - } - else{ - polynomial_prod_chain(tmp_poly, output, fields); - } - free_Polynomial(tmp_poly); - - free(buffer); +int parse_input_polynomial(Char_Array str_polynomial, Polynomial* output, Fields_Table fields, Variables variables){ + parse_symbolic_expression(str_polynomial, fields, variables, output); + polynomial_simplify(output, fields); return(0); } @@ -574,7 +1045,7 @@ int parse_input_polynomial(Char_Array str_polynomial, Polynomial* output, Fields // parse id table // fields argument for sorting -int parse_input_id_table(Char_Array str_idtable, Id_Table* idtable, Fields_Table fields){ +int parse_input_id_table(Char_Array str_idtable, Id_Table* idtable, Fields_Table fields, Variables variables){ // buffer char* buffer=calloc(str_idtable.length+1,sizeof(char)); char* buffer_ptr=buffer; @@ -583,6 +1054,7 @@ int parse_input_id_table(Char_Array str_idtable, Id_Table* idtable, Fields_Table int j; int mode; int comment=0; + int ret; // allocate memory init_Id_Table(idtable,EQUATION_SIZE); @@ -601,24 +1073,40 @@ int parse_input_id_table(Char_Array str_idtable, Id_Table* idtable, Fields_Table case ',': // write polynomial if(mode==PP_POLYNOMIAL_MODE){ - str_to_Polynomial(buffer,&polynomial); + parse_symbolic_expression_str(buffer, fields, variables, &polynomial); // add to idtable idtable_append_noinit(index,polynomial,idtable); mode=PP_INDEX_MODE; buffer_ptr=buffer; *buffer_ptr='\0'; } + else{ + fprintf(stderr,"syntax error: id_table entry (%d): misplaced ','\n",j); + exit(-1); + } break; case ':': if(mode==PP_INDEX_MODE){ - sscanf(buffer,"%d",&index); + ret=read_positive_int(buffer,&index); + if(ret<0){ + fprintf(stderr,"syntax error: id_table entry (%d): index must be a non-negative integer, got '%s'\n",j,buffer); + exit(-1); + } mode=PP_POLYNOMIAL_MODE; buffer_ptr=buffer; *buffer_ptr='\0'; } + else{ + fprintf(stderr,"syntax error: id_table entry (%d): misplaced ':'\n",j); + exit(-1); + } break; + // ignore ' ' and '\n' + case ' ':break; + case '\n':break; + // comment case '#': comment=1; @@ -628,6 +1116,10 @@ int parse_input_id_table(Char_Array str_idtable, Id_Table* idtable, Fields_Table if(mode!=PP_NULL_MODE){ buffer_ptr=str_addchar(buffer_ptr,str_idtable.str[j]); } + else{ + fprintf(stderr,"syntax error: id_table entry (%d): unrecognized character '%c'\n",j, str_idtable.str[j]); + exit(-1); + } break; } } @@ -635,9 +1127,13 @@ int parse_input_id_table(Char_Array str_idtable, Id_Table* idtable, Fields_Table //last step if(mode==PP_POLYNOMIAL_MODE){ - str_to_Polynomial(buffer,&polynomial); + parse_symbolic_expression_str(buffer, fields, variables, &polynomial); idtable_append_noinit(index,polynomial,idtable); } + else if(*buffer!='\0'){ + fprintf(stderr,"syntax error: id_table entry (%d): mismatched index/polynomial pair, got '%s'\n",j,buffer); + exit(-1); + } // sort for(j=0;j<(*idtable).length;j++){ @@ -658,6 +1154,7 @@ int parse_labels(Char_Array str_labels, Labels* labels){ int j; int mode; int comment=0; + int ret; // allocate memory init_Labels(labels,EQUATION_SIZE); @@ -686,18 +1183,30 @@ int parse_labels(Char_Array str_labels, Labels* labels){ buffer_ptr=buffer; *buffer_ptr='\0'; } + else{ + fprintf(stderr,"syntax error: labels entry (%d): mismatched '\"'\n",j); + exit(-1); + } break; case ':': // write if(mode==PP_INDEX_MODE){ sscanf(buffer,"%d",&index); + ret=read_positive_int(buffer,&index); + if(ret<0){ + fprintf(stderr,"syntax error: labels entry (%d): index must be a non-negative integer, got '%s'\n",j,buffer); + exit(-1); + } + } + else{ + fprintf(stderr,"syntax error: labels entry (%d): misplaced ':'\n",j); + exit(-1); } break; // characters to ignore case ' ':break; - case '&':break; case '\n':break; case ',':break; @@ -726,6 +1235,7 @@ int parse_init_cd(Char_Array init_cd, RCC* init, RCC_mpfr* init_mpfr, int mpfr_f int i,j; int comment_mode=0; int dcount=0; + int ret; *buffer_ptr='\0'; // loop over the input @@ -741,7 +1251,11 @@ int parse_init_cd(Char_Array init_cd, RCC* init, RCC_mpfr* init_mpfr, int mpfr_f case ',': // write init if(mpfr_flag==0){ - sscanf(buffer,"%Lf",(*init).values+intlist_find_err((*init).indices,(*init).length,index)); + ret=read_long_double(buffer,(*init).values+intlist_find_err((*init).indices,(*init).length,index)); + if(ret<0){ + fprintf(stderr,"syntax error: initial_condition entry (%d): failed to extract long double from '%s'\n",j,buffer); + exit(-1); + } } else{ mpfr_strtofr((*init_mpfr).values[intlist_find_err((*init_mpfr).indices,(*init_mpfr).length,index)], buffer, &buffer_ptr, 10, MPFR_RNDN); @@ -755,7 +1269,11 @@ int parse_init_cd(Char_Array init_cd, RCC* init, RCC_mpfr* init_mpfr, int mpfr_f // separator case ':': // write index - sscanf(buffer,"%d",&i); + ret=read_int(buffer,&i); + if(ret<0){ + fprintf(stderr,"syntax error: initial_condition entry (%d): index must be an integer, got '%s'\n",j,buffer); + exit(-1); + } if(i<0){ index=i-dcount*DOFFSET; } @@ -772,7 +1290,6 @@ int parse_init_cd(Char_Array init_cd, RCC* init, RCC_mpfr* init_mpfr, int mpfr_f // characters to ignore case ' ':break; - case '&':break; case '\n':break; // comments @@ -790,7 +1307,11 @@ int parse_init_cd(Char_Array init_cd, RCC* init, RCC_mpfr* init_mpfr, int mpfr_f // write init if(mpfr_flag==0){ - sscanf(buffer,"%Lf",(*init).values+intlist_find_err((*init).indices,(*init).length,index)); + ret=read_long_double(buffer,(*init).values+intlist_find_err((*init).indices,(*init).length,index)); + if(ret<0){ + fprintf(stderr,"syntax error: initial_condition entry (%d): failed to extract long double from '%s'\n",j,buffer); + exit(-1); + } } else{ mpfr_strtofr((*init_mpfr).values[intlist_find_err((*init_mpfr).indices,(*init_mpfr).length,index)], buffer, &buffer_ptr, 10, MPFR_RNDN); |