Ian Jauslin
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/parse_file.c')
-rw-r--r--src/parse_file.c717
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);