Beispiel #1
0
const char *get_type(RfListItem *typed)
{
    if (!typed)
        return "*0";
    if (typed->IsChar()) {
        if (is_capital(typed->charcode))
            return "Lu";
        if (is_lower(typed->charcode))
            return "Ll";
        return "Ol";
    }
    if (typed->IsLeftMarkup())
        return "B0";
    SExpressionInt *ti;
    ti = typed->symb_val.DynamicCastGetPtr<SExpressionInt>();
    if (ti)
        return "N0";
    SExpressionFloat *tf;
    tf = typed->symb_val.DynamicCastGetPtr<SExpressionFloat>();
    if (tf)
        return "D0";
    SString repr = typed->symb_val->TextRepresentation();
    char *str = (char *)repr.c_str();
    if (is_ident(str))
        return "Wi";
    return "Wq";
}
Beispiel #2
0
/* parse an entry reference string into routine, label & offset */
void lref_parse(unsigned char *label_ref, mstr* routine, mstr* label, int* offset)
{
	unsigned char 	ch, *c, *c1;
	int 		i, label_len;
	error_def	(ERR_RUNPARAMERR);

	routine->addr = label->addr = (char *)label_ref;
	*offset = 0;
	label_len = STRLEN((const char *)label_ref);
	for (i = 0, c = label_ref;  i < label_len;  i++)
	{
		ch = *c++;
		if (ch == '^'  ||  ch == '+')
		{
			label->len = i;

			if (ch == '+')
			{
				*offset = (int)STRTOL((const char *)c, (char**)&c1, 10);
				if (c == c1 ||*c1 != '^')
					rts_error(VARLSTCNT(1) ERR_RUNPARAMERR);
				c = c1 + 1;
			}
			routine->addr = (char *)c;
			routine->len = INTCAST(label_ref + label_len - c);
			break;
		}
	}
	if (routine->addr == (char *)label_ref)
	{
		routine->len = label_len;
		routine->addr = (char *)label_ref;
		label->len = 0;
	}
	if (!is_ident(routine))
		rts_error(VARLSTCNT(1) ERR_RUNPARAMERR);
	if (label->len && !is_ident(label))
		rts_error(VARLSTCNT(1) ERR_RUNPARAMERR);

	routine->len = routine->len > MAX_MIDENT_LEN ? MAX_MIDENT_LEN : routine->len;
	label->len = label->len > MAX_MIDENT_LEN ? MAX_MIDENT_LEN : label->len;
}
Beispiel #3
0
void write_cmos_layout_header(const char *header_filename)
{
	FILE *fp;
	const cmos_entry_t *cmos_entry;
	cmos_checksum_layout_t layout;

	if ((fp = fopen(header_filename, "w+")) == NULL) {
		fprintf(stderr,
				"%s: Can't open file %s for writing: %s\n",
				prog_name, header_filename, strerror(errno));
			exit(1);
	}

	fprintf(fp, "/**\n * This is an autogenerated file. Do not EDIT.\n"
			" * All changes made to this file will be lost.\n"
			" * See mainboard's cmos.layout file.\n */\n"
			"\n#ifndef __OPTION_TABLE_H\n"
			"#define __OPTION_TABLE_H\n\n");

	for (cmos_entry = first_cmos_entry(); cmos_entry != NULL;
			cmos_entry = next_cmos_entry(cmos_entry)) {

		if (!is_ident((char *)cmos_entry->name)) {
			fprintf(stderr,
				"Error - Name %s is an invalid identifier\n",
				cmos_entry->name);
			fclose(fp);
			exit(1);
		}

		fprintf(fp, "#define CMOS_VSTART_%s\t%d\n",
				cmos_entry->name, cmos_entry->bit);
		fprintf(fp, "#define CMOS_VLEN_%s\t%d\n",
				cmos_entry->name, cmos_entry->length);
	}

	layout.summed_area_start = cmos_checksum_start;
	layout.summed_area_end = cmos_checksum_end;
	layout.checksum_at = cmos_checksum_index;
	checksum_layout_to_bits(&layout);

	fprintf(fp, "\n#define LB_CKS_RANGE_START %d\n",
			layout.summed_area_start / 8);
	fprintf(fp, "#define LB_CKS_RANGE_END %d\n",
			layout.summed_area_end / 8);
	fprintf(fp, "#define LB_CKS_LOC %d\n",
			layout.checksum_at / 8);
	fprintf(fp, "\n#endif /* __OPTION_TABLE_H */\n");

	fclose(fp);
}
Beispiel #4
0
int inv_test(u8 * in, u8 * inv, u8 * sav, int n)
{
	memcpy(sav, in, n * n);

	if (gf_invert_matrix(in, inv, n)) {
		printf("Given singular matrix\n");
		print_matrix(sav, n);
		return -1;
	}

	matrix_mult(inv, sav, in, n);

	if (is_ident(in, n)) {
		printf("fail\n");
		print_matrix(sav, n);
		print_matrix(inv, n);
		print_matrix(in, n);
		return -1;
	}
	putchar('.');

	return 0;
}
Beispiel #5
0
/**
 * This routine builds the cmos definition table from the cmos layout file
 *
 * The input comes from the configuration file which contains two parts
 * entries and enumerations.  Each section is started with the key words
 * entries and enumerations.  Records then follow in their respective
 * formats.
 *
 * The output of this program is the cmos definitions table.  It is stored
 * in the cmos_table array. If this module is called, and the global
 * table_file has been implimented by the user, the table is also written
 * to the specified file.
 *
 * This program exits with a return code of 1 on error.  It returns 0 on
 * successful completion
 */
int main(int argc, char **argv)
{
	int i;
	char *config=0;
	char *binary=0;
	char *option=0;
	char *header=0;
	FILE *fp;
	int tempfile;
	char tempfilename[TMPFILE_LEN];
	struct cmos_option_table *ct;
	struct cmos_entries *ce;
	struct cmos_enums *c_enums, *c_enums_start;
	struct cmos_checksum *cs, *new_cs;
	char line[INPUT_LINE_MAX];
	unsigned char uc;
	int entry_mode=0;
	int enum_mode=0;
	int checksum_mode=0;
	int cnt;
	char *cptr;
	void *entry_start, *entry_end;
	int entries_length;
	int enum_length;
	int len;
	char buf[16];
	char val;

        for(i=1;i<argc;i++) {
                if(argv[i][0]!='-') {
                        display_usage(argv[0]);
                }
                switch(argv[i][1]) {
                        case '-':       /* data is requested from a file */
                                switch(argv[i][2]) {
                                        case 'c':  /* use a configuration file */
                                                if(strcmp(&argv[i][2],"config")) {
                                                        display_usage(argv[0]);
                                                }
                                                config=argv[++i];
                                                break;
                                        case 'b':  /* Emit a binary file */
                                                if(strcmp(&argv[i][2],"binary")) {
                                                        display_usage(argv[0]);
                                                }
                                                binary=argv[++i];
                                                break;
                                        case 'o':  /* use a cmos definitions table file */
                                                if(strcmp(&argv[i][2],"option")) {
                                                        display_usage(argv[0]);
                                                }
                                                option=argv[++i];
                                                break;
					case 'h': /* Output a header file */
						if (strcmp(&argv[i][2], "header") != 0) {
							display_usage(argv[0]);
						}
						header=argv[++i];
						break;
                                        default:
                                                display_usage(argv[0]);
                                                break;
                                }
                                break;

                        default:
                                display_usage(argv[0]);
                                break;
                }
        }


	/* Has the user specified a configuration file */
	if(config) {	/* if yes, open it */
		if((fp=fopen(config,"r"))==NULL){
			fprintf(stderr, "Error - Can not open config file %s\n",config);
			exit(1);  /* exit if it can not be opened */
		}
	}
	else {  /* no configuration file specified, so try the default */
		if((fp=fopen("cmos.layout","r"))==NULL){
			fprintf(stderr, "Error - Can not open cmos.layout\n");
			exit(1);  /* end of no configuration file is found */
		}
	}
	/* type cast a pointer, so we can us the structure */
	ct=(struct cmos_option_table*)cmos_table;
	/* start the table with the type signature */
	ct->tag = LB_TAG_CMOS_OPTION_TABLE;
	/* put in the header length */
	ct->header_length=sizeof(*ct);

	/* Get the entry records */
	ce=(struct cmos_entries*)(cmos_table+(ct->header_length));
	cptr = (char*)ce;
	for(;;){  /* this section loops through the entry records */
		if(fgets(line,INPUT_LINE_MAX,fp)==NULL)
			break; /* end if no more input */
		// FIXME mode should be a single enum.
		if(!entry_mode) {  /* skip input until the entries key word */
			if (strstr(line,"entries") != 0) {
				entry_mode=1;
				enum_mode=0;
				checksum_mode=0;
				continue;
			}
		} else {  /* Test if we are done with entries and starting enumerations */
			if (strstr(line,"enumerations") != 0){
				entry_mode=0;
				enum_mode=1;
				checksum_mode=0;
				break;
			}
			if (strstr(line, "checksums") != 0) {
				entry_mode=0;
				enum_mode=0;
				checksum_mode=1;
				break;
			}
		}

		/* skip commented and blank lines */
		val = line[strspn(line," ")];
		/* takes care of *nix, Mac and Windows line ending formats */
		if (val=='#' || val=='\n' || val=='\r') continue;
		/* scan in the input data */
		sscanf(line,"%d %d %c %d %s",
			&ce->bit,&ce->length,&uc,&ce->config_id,&ce->name[0]);
		ce->config=(int)uc;
		/* check bit and length ranges */
		if(ce->bit>(CMOS_IMAGE_BUFFER_SIZE*8)) {
                        fprintf(stderr, "Error - bit is to big in line \n%s\n",line);
                        exit(1);
                }
		if((ce->length>(MAX_VALUE_BYTE_LENGTH*8))&&(uc!='r')) {
			fprintf(stderr, "Error - Length is to long in line \n%s\n",line);
			exit(1);
		}
		if (!is_ident((char *)ce->name)) {
			fprintf(stderr,
				"Error - Name %s is an invalid identifier in line\n %s\n",
				ce->name, line);
			exit(1);
		}
		/* put in the record type */
		ce->tag=LB_TAG_OPTION;
		/* calculate and save the record length */
		len=strlen((char *)ce->name)+1;
		/* make the record int aligned */
		if(len%4)
			len+=(4-(len%4));
		ce->size=sizeof(struct cmos_entries)-32+len;
		cptr = (char*)ce;
		cptr += ce->size;  /* increment to the next table position */
		ce = (struct cmos_entries*) cptr;
	}

	/* put the length of the entries into the header section */
	entries_length = (cptr - (char *)&cmos_table) - ct->header_length;

	/* compute the start of the enumerations section */
	entry_start = ((char*)&cmos_table) + ct->header_length;
	entry_end   = ((char *)entry_start) + entries_length;
	c_enums_start = c_enums = (struct cmos_enums*)entry_end;
  	/* test for overlaps in the entry records */
	test_for_entry_overlaps(entry_start, entry_end);

	for(;enum_mode;){ /* loop to build the enumerations section */
		long ptr;
		if(fgets(line,INPUT_LINE_MAX,fp)==NULL)
			break; /* go till end of input */

		if (strstr(line, "checksums") != 0) {
			enum_mode=0;
			checksum_mode=1;
			break;
		}

		/* skip commented and blank lines */
		if(line[0]=='#') continue;
		if(line[strspn(line," ")]=='\n') continue;

		/* scan in the data */
		for(ptr=0;(line[ptr]==' ')||(line[ptr]=='\t');ptr++);
		c_enums->config_id=strtol(&line[ptr],(char**)NULL,10);
		for(;(line[ptr]!=' ')&&(line[ptr]!='\t');ptr++);
		for(;(line[ptr]==' ')||(line[ptr]=='\t');ptr++);
		c_enums->value=strtol(&line[ptr],(char**)NULL,10);
		for(;(line[ptr]!=' ')&&(line[ptr]!='\t');ptr++);
		for(;(line[ptr]==' ')||(line[ptr]=='\t');ptr++);
		for(cnt=0;(line[ptr]!='\n')&&(cnt<31);ptr++,cnt++)
			c_enums->text[cnt]=line[ptr];
		c_enums->text[cnt]=0;

		/* make the record int aligned */
		cnt++;
		if(cnt%4)
			cnt+=4-(cnt%4);
		/* store the record length */
		c_enums->size=((char *)&c_enums->text[cnt]) - (char *)c_enums;
		/* store the record type */
		c_enums->tag=LB_TAG_OPTION_ENUM;
		/* increment to the next record */
		c_enums=(struct cmos_enums*)&c_enums->text[cnt];
	}
	/* save the enumerations length */
	enum_length= (char *)c_enums - (char *)c_enums_start;
	ct->size=ct->header_length+enum_length+entries_length;

	/* Get the checksum records */
	new_cs = (struct cmos_checksum *)(cmos_table+(ct->size));
	for(;checksum_mode;) { /* This section finds the checksums */
		char *ptr;
		if(fgets(line, INPUT_LINE_MAX,fp)==NULL)
			break; /* end if no more input */

		/* skip commented and blank lines */
		if (line[0]=='#') continue;
		if (line[strspn(line, " ")]=='\n') continue;
		if (memcmp(line, "checksum", 8) != 0) continue;

		/* We actually found a new cmos checksum entry */
		cs = new_cs;

		/* get the information */
		ptr = line + 8;
		skip_spaces(line, &ptr);
		cs->range_start = get_number(line, &ptr, 10);

		skip_spaces(line, &ptr);
		cs->range_end = get_number(line, &ptr, 10);

		skip_spaces(line, &ptr);
		cs->location = get_number(line, &ptr, 10);

		/* Make certain there are spaces until the end of the line */
		skip_spaces(line, &ptr);

		if ((cs->range_start%8) != 0) {
			fprintf(stderr, "Error - range start is not byte aligned in line\n%s\n", line);
			exit(1);
		}
		if (cs->range_start >= (CMOS_IMAGE_BUFFER_SIZE*8)) {
			fprintf(stderr, "Error - range start is to big in line\n%s\n", line);
			exit(1);
		}
		if ((cs->range_end%8) != 7) {
			fprintf(stderr, "Error - range end is not byte aligned in line\n%s\n", line);
			exit(1);
		}
		if ((cs->range_end) >= (CMOS_IMAGE_BUFFER_SIZE*8)) {
			fprintf(stderr, "Error - range end is to long in line\n%s\n", line);
			exit(1);
		}
		if ((cs->location%8) != 0) {
			fprintf(stderr, "Error - location is not byte aligned in line\n%s\n", line);
			exit(1);
		}
		if ((cs->location >= (CMOS_IMAGE_BUFFER_SIZE*8)) ||
			((cs->location + 16) > (CMOS_IMAGE_BUFFER_SIZE*8)))
		{
			fprintf(stderr, "Error - location is to big in line\n%s\n", line);
			exit(1);
		}

		cs->tag = LB_TAG_OPTION_CHECKSUM;
		cs->size = sizeof(*cs);
		cs->type = CHECKSUM_PCBIOS;

		cptr = (char *)cs;
		cptr += cs->size;
		new_cs = (struct cmos_checksum *)cptr;
	}
	ct->size += (cptr - (char *)(cmos_table + ct->size));
	fclose(fp);

	/* See if we want to output a C source file */
	if(option) {
		int err=0;
		snprintf(tempfilename, TMPFILE_LEN, "%s%s", dirname(strdup(option)), TMPFILE_TEMPLATE);
		tempfile = mkstemp(tempfilename);
		if(tempfile == -1) {
                        perror("Error - Could not create temporary file");
                        exit(1);
		}

		if((fp=fdopen(tempfile,"w"))==NULL){
			perror("Error - Could not open temporary file");
			unlink(tempfilename);
			exit(1);
		}

		/* write the header */
        	if(fwrite("unsigned char option_table[] = {",1,32,fp) != 32) {
        	        perror("Error - Could not write image file");
        	        fclose(fp);
			unlink(tempfilename);
        	        exit(1);
        	}
		/* write the array values */
		for(i=0; i<(int)(ct->size-1); i++) {
			if(!(i%10) && !err) err=(fwrite("\n\t",1,2,fp) != 2);
			sprintf(buf,"0x%02x,",cmos_table[i]);
			if(!err) err=(fwrite(buf,1,5,fp) != 5);
		}
		/* write the end */
		sprintf(buf,"0x%02x\n",cmos_table[i]);
		if(!err) err=(fwrite(buf,1,4,fp) != 4);
        	if(fwrite("};\n",1,3,fp) != 3) {
        	        perror("Error - Could not write image file");
        	        fclose(fp);
			unlink(tempfilename);
        	        exit(1);
        	}

        	fclose(fp);
		UNLINK_IF_NECESSARY(option);
		if (rename(tempfilename, option)) {
			fprintf(stderr, "Error - Could not write %s: ", option);
			perror(NULL);
			unlink(tempfilename);
			exit(1);
		}
	}

	/* See if we also want to output a binary file */
	if(binary) {
		int err=0;
		snprintf(tempfilename, TMPFILE_LEN, "%s%s", dirname(strdup(binary)), TMPFILE_TEMPLATE);
		tempfile = mkstemp(tempfilename);
		if(tempfile == -1) {
                        perror("Error - Could not create temporary file");
                        exit(1);
		}

		if((fp=fdopen(tempfile,"wb"))==NULL){
			perror("Error - Could not open temporary file");
			unlink(tempfilename);
			exit(1);
		}

		/* write the array values */
		if(fwrite(cmos_table, (int)(ct->size-1), 1, fp) != 1) {
        	        perror("Error - Could not write image file");
        	        fclose(fp);
			unlink(tempfilename);
        	        exit(1);
		}

        	fclose(fp);
		UNLINK_IF_NECESSARY(binary);
		if (rename(tempfilename, binary)) {
			fprintf(stderr, "Error - Could not write %s: ", binary);
			perror(NULL);
			unlink(tempfilename);
			exit(1);
		}
	}

	/* See if we also want to output a C header file */
	if (header) {
		struct cmos_option_table *hdr;
		struct lb_record *ptr, *end;

		snprintf(tempfilename, TMPFILE_LEN, "%s%s", dirname(strdup(header)), TMPFILE_TEMPLATE);
		tempfile = mkstemp(tempfilename);
		if(tempfile == -1) {
			perror("Error - Could not create temporary file");
			exit(1);
		}

		fp = fdopen(tempfile, "w");
		if (!fp) {
			perror("Error - Could not open temporary file");
			unlink(tempfilename);
			exit(1);
		}

		/* Get the cmos table header */
		hdr = (struct cmos_option_table *)cmos_table;
		/* Walk through the entry records */
		ptr = (struct lb_record *)(cmos_table + hdr->header_length);
		end = (struct lb_record *)(cmos_table + hdr->size);
		fprintf(fp, "/* This file is autogenerated.\n"
			    " * See mainboard's cmos.layout file.\n */\n\n"
			    "#ifndef __OPTION_TABLE_H\n#define __OPTION_TABLE_H\n\n");

		for(;ptr < end; ptr = (struct lb_record *)(((char *)ptr) + ptr->size)) {
			if (ptr->tag != LB_TAG_OPTION) {
				continue;
			}
			ce = (struct cmos_entries *)ptr;

			if (!is_ident((char *)ce->name)) {
				fprintf(stderr, "Invalid identifier: %s\n",
					ce->name);
				fclose(fp);
				unlink(tempfilename);
				exit(1);
			}
			fprintf(fp, "#define CMOS_VSTART_%s %d\n",
				ce->name, ce->bit);
			fprintf(fp, "#define CMOS_VLEN_%s %d\n",
				ce->name, ce->length);
		}

		if (cs != NULL) {
			fprintf(fp, "\n#define LB_CKS_RANGE_START %d\n", cs->range_start / 8);
			fprintf(fp, "#define LB_CKS_RANGE_END %d\n", cs->range_end / 8);
			fprintf(fp, "#define LB_CKS_LOC %d\n", cs->location / 8);
		} else {
			fprintf(stderr, "Error - No checksums defined.\n");
			fclose(fp);
			unlink(tempfilename);
			exit(1);
		}
		fprintf(fp, "\n#endif // __OPTION_TABLE_H\n");
		fclose(fp);

		UNLINK_IF_NECESSARY(header);
		if (rename(tempfilename, header)) {
			fprintf(stderr, "Error - Could not write %s: ", header);
			perror(NULL);
			unlink(tempfilename);
			exit(1);
		}
	}

	return 0;
}
Beispiel #6
0
int write_cmos_layout_bin(FILE *f)
{
	const cmos_entry_t *cmos_entry;
	const cmos_enum_t *cmos_enum;
	cmos_checksum_layout_t layout;
	struct cmos_option_table table;
	struct cmos_entries entry;
	struct cmos_enums cenum;
	struct cmos_checksum csum;
	size_t sum = 0;
	int len;

	for (cmos_entry = first_cmos_entry(); cmos_entry != NULL;
			cmos_entry = next_cmos_entry(cmos_entry)) {

		if (cmos_entry == first_cmos_entry()) {
			sum += sizeof(table);
			table.header_length = sizeof(table);
			table.tag = LB_TAG_CMOS_OPTION_TABLE;
			table.size = 0;

			if (fwrite((char *)&table, sizeof(table), 1, f) != 1) {
				perror("Error writing image file");
				goto err;
			}
		}

		memset(&entry, 0, sizeof(entry));
		entry.tag = LB_TAG_OPTION;
		entry.config = cmos_entry->config;
		entry.config_id = (uint32_t)cmos_entry->config_id;
		entry.bit = cmos_entry->bit;
		entry.length = cmos_entry->length;

		if (!is_ident((char *)cmos_entry->name)) {
			fprintf(stderr,
				"Error - Name %s is an invalid identifier\n",
				cmos_entry->name);
			goto err;
		}

		memcpy(entry.name, cmos_entry->name, strlen(cmos_entry->name));
		entry.name[strlen(cmos_entry->name)] = '\0';
		len = strlen(cmos_entry->name) + 1;

		if (len % 4)
			ROUNDUP4(len);

		entry.size = sizeof(entry) - CMOS_MAX_NAME_LENGTH + len;
		sum += entry.size;
		if (fwrite((char *)&entry, entry.size, 1, f) != 1) {
			perror("Error writing image file");
			goto err;
		}
	}

	for (cmos_enum = first_cmos_enum();
			cmos_enum != NULL; cmos_enum = next_cmos_enum(cmos_enum)) {
		memset(&cenum, 0, sizeof(cenum));
		cenum.tag = LB_TAG_OPTION_ENUM;
		memcpy(cenum.text, cmos_enum->text, strlen(cmos_enum->text));
		cenum.text[strlen(cmos_enum->text)] = '\0';
		len = strlen((char *)cenum.text) + 1;

		if (len % 4)
			ROUNDUP4(len);

		cenum.config_id = cmos_enum->config_id;
		cenum.value = cmos_enum->value;
		cenum.size = sizeof(cenum) - CMOS_MAX_TEXT_LENGTH + len;
		sum += cenum.size;
		if (fwrite((char *)&cenum, cenum.size, 1, f) != 1) {
			perror("Error writing image file");
			goto err;
		}
	}

	layout.summed_area_start = cmos_checksum_start;
	layout.summed_area_end = cmos_checksum_end;
	layout.checksum_at = cmos_checksum_index;
	checksum_layout_to_bits(&layout);

	csum.tag = LB_TAG_OPTION_CHECKSUM;
	csum.size = sizeof(csum);
	csum.range_start = layout.summed_area_start;
	csum.range_end = layout.summed_area_end;
	csum.location = layout.checksum_at;
	csum.type = CHECKSUM_PCBIOS;
	sum += csum.size;

	if (fwrite((char *)&csum, csum.size, 1, f) != 1) {
		perror("Error writing image file");
		goto err;
	}

	if (fseek(f, 0, SEEK_SET) != 0) {
		perror("Error while seeking");
		goto err;
	}

	table.size = sum;
	if (fwrite((char *)&table, sizeof(table), 1, f) != 1) {
		perror("Error writing image file");
		goto err;
	}
	return sum;

err:
	fclose(f);
	exit(1);
}
Beispiel #7
0
/**
 * \brief Read a token from a buffer
 * \param File	Parser state
 */
int GetToken(tParser *File)
{
	 int	ret;

	if( File->ErrorHit ) {
		return TOK_INVAL;
	}
	
	if( File->NextState.Token != TOK_INVAL ) {
		// Save Last
		File->PrevState = File->Cur;
		// Restore Next
		File->Cur = File->NextState;
		// Set State
		File->CurPos = File->Cur.TokenStr + File->Cur.TokenLen;
		File->NextState.Token = TOK_INVAL;
		#if DEBUG
		printf(" GetToken: FAST Return %i (%i long) (%.*s)\n", File->Cur.Token, File->Cur.TokenLen,
			File->Cur.TokenLen, File->Cur.TokenStr);
		#endif
		return File->Cur.Token;
	}
	
	//printf("  GetToken: File=%p, File->CurPos = %p\n", File, File->CurPos);
	
	// Clear whitespace (including comments)
	for( ;; )
	{
		// Whitespace
		while( isspace( *File->CurPos ) )
		{
			//printf("whitespace 0x%x, line = %i\n", *File->CurPos, File->CurLine);
			if( *File->CurPos == '\n' )
				File->Cur.Line ++;
			File->CurPos ++;
		}
		
		// # Line Comments
		if( *File->CurPos == '#' ) {
			while( *File->CurPos && *File->CurPos != '\n' )
				File->CurPos ++;
			continue ;
		}
		
		// C-Style Line Comments
		if( *File->CurPos == '/' && File->CurPos[1] == '/' ) {
			while( *File->CurPos && *File->CurPos != '\n' )
				File->CurPos ++;
			continue ;
		}
		
		// C-Style Block Comments
		if( *File->CurPos == '/' && File->CurPos[1] == '*' ) {
			File->CurPos += 2;	// Eat the '/*'
			while( *File->CurPos && !(File->CurPos[-1] == '*' && *File->CurPos == '/') )
			{
				if( *File->CurPos == '\n' )
					File->Cur.Line ++;
				File->CurPos ++;
			}
			File->CurPos ++;	// Eat the '/'
			continue ;
		}
		
		// No more "whitespace"
		break;
	}
	
	// Save previous tokens (speeds up PutBack and LookAhead)
	File->PrevState = File->Cur;
	
	// Read token
	File->Cur.TokenStr = File->CurPos;
	switch( *File->CurPos++ )
	{
	case '\0':	ret = TOK_EOF;	break;
	
	// Operations
	case '^':
		if( *File->CurPos == '^' ) {
			File->CurPos ++;
			ret = TOK_LOGICXOR;
			break;
		}
		ret = TOK_XOR;
		break;
	
	case '|':
		if( *File->CurPos == '|' ) {
			File->CurPos ++;
			ret = TOK_LOGICOR;
			break;
		}
		ret = TOK_OR;
		break;
	
	case '&':
		if( *File->CurPos == '&' ) {
			File->CurPos ++;
			ret = TOK_LOGICAND;
			break;
		}
		ret = TOK_AND;
		break;
	
	case '/':
		if( *File->CurPos == '=' ) {
			File->CurPos ++;
			ret = TOK_ASSIGN_DIV;
			break;
		}
		ret = TOK_DIV;
		break;
	case '%':
		if( *File->CurPos == '=' ) {
			File->CurPos ++;
			ret = TOK_ASSIGN_MODULO;
			break;
		}
		ret = TOK_MODULO;
		break;
	case '*':
		if( *File->CurPos == '=' ) {
			File->CurPos ++;
			ret = TOK_ASSIGN_MUL;
			break;
		}
		ret = TOK_MUL;
		break;
	case '+':
		if( *File->CurPos == '+' ) {
			File->CurPos ++;
			ret = TOK_INCREMENT;
			break;
		}
		if( *File->CurPos == '=' ) {
			File->CurPos ++;
			ret = TOK_ASSIGN_PLUS;
			break;
		}
		ret = TOK_PLUS;
		break;
	case '-':
		if( *File->CurPos == '-' ) {
			File->CurPos ++;
			ret = TOK_DECREMENT;
			break;
		}
		if( *File->CurPos == '=' ) {
			File->CurPos ++;
			ret = TOK_ASSIGN_MINUS;
			break;
		}
		if( *File->CurPos == '>' ) {
			File->CurPos ++;
			ret = TOK_ELEMENT;
			break;
		}
		ret = TOK_MINUS;
		break;
	
	// Strings
	case '"':
		while( *File->CurPos && !(*File->CurPos == '"' && File->CurPos[-1] != '\\') )
			File->CurPos ++;
		if( *File->CurPos )
		{
			File->CurPos ++;
			ret = TOK_STR;
		}
		else
			ret = TOK_EOF;
		break;
	
	// Brackets
	case '(':	ret = TOK_PAREN_OPEN;	break;
	case ')':	ret = TOK_PAREN_CLOSE;	break;
	case '{':	ret = TOK_BRACE_OPEN;	break;
	case '}':	ret = TOK_BRACE_CLOSE;	break;
	case '[':	ret = TOK_SQUARE_OPEN;	break;
	case ']':	ret = TOK_SQUARE_CLOSE;	break;
	
	// Core symbols
	case ';':	ret = TOK_SEMICOLON;	break;
	case ',':	ret = TOK_COMMA;	break;
	case ':':	ret = TOK_COLON;	break;
	case '?':
		if( *File->CurPos == ':' ) {
			File->CurPos ++;
			ret = TOK_QMARKCOLON;
		}
		else
			ret = TOK_QUESTIONMARK;
		break;
	case '.':
		if( *File->CurPos == '.' && File->CurPos[1] == '.' ) {
			File->CurPos += 2;
			ret = TOK_ELIPSIS;
		}
		else
			#if USE_SCOPE_CHAR
			ret = TOK_SCOPE;
			#else
			goto default;
			#endif
		break;
	
	// Equals
	case '=':
		if( *File->CurPos != '=' ) {
			// Assignment Equals
			ret = TOK_ASSIGN;
			break;
		}
		File->CurPos ++;
		if( *File->CurPos != '=' ) {
			// Comparison Equals
			ret = TOK_EQUALS;
			break;
		}
		File->CurPos ++;
		ret = TOK_REFEQUALS;
		break;
	
	// Less-Than
	case '<':
		// Less-Than or Equal
		if( *File->CurPos == '=' ) {
			File->CurPos ++;
			ret = TOK_LTE;
			break;
		}
		ret = TOK_LT;
		break;
	
	// Greater-Than
	case '>':
		// Greater-Than or Equal
		if( *File->CurPos == '=' ) {
			File->CurPos ++;
			ret = TOK_GTE;
			break;
		}
		ret = TOK_GT;
		break;
	
	// Logical NOT
	case '!':
		if( *File->CurPos != '=' ) {
			ret = TOK_LOGICNOT;
			break;
		}
		File->CurPos ++;
		if( *File->CurPos != '=' ) {
			ret = TOK_NOTEQUALS;
			break;
		}
		File->CurPos ++;
		ret = TOK_REFNOTEQUALS;
		break;
	// Bitwise NOT
	case '~':
		ret = TOK_BWNOT;
		break;
	
	// Variables
	// \$[0-9]+ or \$[_a-zA-Z][_a-zA-Z0-9]*
	case '$':
		// Numeric Variable
		if( isdigit( *File->CurPos ) ) {
			while( isdigit(*File->CurPos) )
				File->CurPos ++;
		}
		// Ident Variable
		else {
			while( is_ident(*File->CurPos) || isdigit(*File->CurPos) )
				File->CurPos ++;
		}
		ret = TOK_VARIABLE;
		break;
	
	// Default (Numbers and Identifiers)
	default:
		File->CurPos --;
		
		// Numbers
		if( isdigit(*File->CurPos) )
		{
			ret = TOK_INTEGER;
			if( *File->CurPos == '0' && File->CurPos[1] == 'x' )
			{
				File->CurPos += 2;
				while(('0' <= *File->CurPos && *File->CurPos <= '9')
				   || ('A' <= *File->CurPos && *File->CurPos <= 'F')
				   || ('a' <= *File->CurPos && *File->CurPos <= 'f') )
				{
					File->CurPos ++;
				}
			}
			else
			{
				while( isdigit(*File->CurPos) )
					File->CurPos ++;
				
//				printf("*File->CurPos = '%c'\n", *File->CurPos);
				
				// Decimal
				if( *File->CurPos == '.' )
				{
					ret = TOK_REAL;
					File->CurPos ++;
					while( isdigit(*File->CurPos) )
						File->CurPos ++;
				}
				// Exponent
				if( *File->CurPos == 'e' || *File->CurPos == 'E' )
				{
					ret = TOK_REAL;
					File->CurPos ++;
					if(*File->CurPos == '-' || *File->CurPos == '+')
						File->CurPos ++;
					while( isdigit(*File->CurPos) )
						File->CurPos ++;
				}
				
//				printf(" ret = %i\n", ret);
			}
			break;
		}
	
		// Identifier
		if( is_ident(*File->CurPos) )
		{
			ret = TOK_IDENT;
			
			// Identifier
			while( is_ident(*File->CurPos) || isdigit(*File->CurPos) )
				File->CurPos ++;
			
			// This is set later too, but we use it below
			const char *tokstr = File->Cur.TokenStr;
			size_t	len = File->CurPos - tokstr;
			
			// Check if it's a reserved word
			for( int i = 0; i < ARRAY_SIZE(csaReservedWords); i ++ )
			{
				if( strncmp(csaReservedWords[i].Name, tokstr, len) != 0 )
					continue ;
				if( csaReservedWords[i].Name[len] != '\0' )
					continue ;
				ret = csaReservedWords[i].Value;
				break ;
			}
			// If there's no match, just keep ret as TOK_IDENT
			
			break;
		}
		// Syntax Error
		ret = TOK_INVAL;
		File->ErrorHit = 1;
		SyntaxError_(File, -1, "Unknown symbol '%c'", *File->CurPos);
		break;
	}
	// Return
	File->Cur.Token = ret;
	File->Cur.TokenLen = File->CurPos - File->Cur.TokenStr;
	
	#if DEBUG
	printf(" GetToken: Return %i (%i long) (%.*s)\n", ret, File->Cur.TokenLen,
		File->Cur.TokenLen, File->Cur.TokenStr);
	#endif
	return ret;
}
Beispiel #8
0
static enum rules_token
lex(struct scanner *s, union lvalue *val)
{
skip_more_whitespace_and_comments:
    /* Skip spaces. */
    while (chr(s, ' ') || chr(s, '\t'));

    /* Skip comments. */
    if (lit(s, "//")) {
        while (!eof(s) && !eol(s)) next(s);
    }

    /* New line. */
    if (eol(s)) {
        while (eol(s)) next(s);
        return TOK_END_OF_LINE;
    }

    /* Escaped line continuation. */
    if (chr(s, '\\')) {
        if (!eol(s)) {
            scanner_err(s, "illegal new line escape; must appear at end of line");
            return TOK_ERROR;
        }
        next(s);
        goto skip_more_whitespace_and_comments;
    }

    /* See if we're done. */
    if (eof(s)) return TOK_END_OF_FILE;

    /* New token. */
    s->token_line = s->line;
    s->token_column = s->column;

    /* Operators and punctuation. */
    if (chr(s, '!')) return TOK_BANG;
    if (chr(s, '=')) return TOK_EQUALS;
    if (chr(s, '*')) return TOK_STAR;

    /* Group name. */
    if (chr(s, '$')) {
        val->string.start = s->s + s->pos;
        val->string.len = 0;
        while (is_ident(peek(s))) {
            next(s);
            val->string.len++;
        }
        if (val->string.len == 0) {
            scanner_err(s, "unexpected character after \'$\'; expected name");
            return TOK_ERROR;
        }
        return TOK_GROUP_NAME;
    }

    /* Identifier. */
    if (is_ident(peek(s))) {
        val->string.start = s->s + s->pos;
        val->string.len = 0;
        while (is_ident(peek(s))) {
            next(s);
            val->string.len++;
        }
        return TOK_IDENTIFIER;
    }

    scanner_err(s, "unrecognized token");
    return TOK_ERROR;
}
Beispiel #9
0
static bool shunting_yard(const TCHAR *input, TCHAR *output)
{
    const TCHAR *strpos = input, *strend = input + _tcslen(input);
    TCHAR c, *outpos = output;
 
    TCHAR stack[STACK_SIZE];       // operator stack
    unsigned int sl = 0;  // stack length
    TCHAR    sc;          // used for record stack element
 
    while(strpos < strend)   {
		if (sl >= STACK_SIZE)
			return false;

		// read one token from the input stream
        c = *strpos;
        if(c != ' ')    {
            // If the token is a number (identifier), then add it to the output queue.
            if(is_ident(c))  {
                *outpos = c; ++outpos;
            }
            // If the token is a function token, then push it onto the stack.
            else if(is_function(c))   {
                stack[sl] = c;
                ++sl;
            }
            // If the token is a function argument separator (e.g., a comma):
            else if(c == ',')   {
                bool pe = false;
                while(sl > 0)   {
                    sc = stack[sl - 1];
                    if(sc == '(')  {
                        pe = true;
                        break;
                    }
                    else  {
                        // Until the token at the top of the stack is a left parenthesis,
                        // pop operators off the stack onto the output queue.
                        *outpos = sc; 
                        ++outpos;
                        sl--;
                    }
                }
                // If no left parentheses are encountered, either the separator was misplaced
                // or parentheses were mismatched.
                if(!pe)   {
                    calc_log ((_T("Error: separator or parentheses mismatched\n")));
                    return false;
                }
            }
            // If the token is an operator, op1, then:
            else if(is_operator(c))  {
                while(sl > 0)    {
                    sc = stack[sl - 1];
                    // While there is an operator token, o2, at the top of the stack
                    // op1 is left-associative and its precedence is less than or equal to that of op2,
                    // or op1 is right-associative and its precedence is less than that of op2,
                    if(is_operator(sc) &&
                        ((op_left_assoc(c) && (op_preced(c) <= op_preced(sc))) ||
                           (!op_left_assoc(c) && (op_preced(c) < op_preced(sc)))))   {
                        // Pop o2 off the stack, onto the output queue;
                        *outpos = sc; 
                        ++outpos;
                        sl--;
                    }
                    else   {
                        break;
                    }
                }
                // push op1 onto the stack.
                stack[sl] = c;
                ++sl;
            }
            // If the token is a left parenthesis, then push it onto the stack.
            else if(c == '(')   {
                stack[sl] = c;
                ++sl;
            }
            // If the token is a right parenthesis:
            else if(c == ')')    {
                bool pe = false;
                // Until the token at the top of the stack is a left parenthesis,
                // pop operators off the stack onto the output queue
                while(sl > 0)     {
                    sc = stack[sl - 1];
                    if(sc == '(')    {
                        pe = true;
                        break;
                    }
                    else  {
                        *outpos = sc; 
                        ++outpos;
                        sl--;
                    }
                }
                // If the stack runs out without finding a left parenthesis, then there are mismatched parentheses.
                if(!pe)  {
                    calc_log ((_T("Error: parentheses mismatched\n")));
                    return false;
                }
                // Pop the left parenthesis from the stack, but not onto the output queue.
                sl--;
                // If the token at the top of the stack is a function token, pop it onto the output queue.
                if(sl > 0)   {
                    sc = stack[sl - 1];
                    if(is_function(sc))   {
                        *outpos = sc; 
                        ++outpos;
                        sl--;
                    }
                }
            }
            else  {
                calc_log ((_T("Unknown token %c\n"), c));
                return false; // Unknown token
            }
        }
        ++strpos;
    }
    // When there are no more tokens to read:
    // While there are still operator tokens in the stack:
    while(sl > 0)  {
        sc = stack[sl - 1];
        if(sc == '(' || sc == ')')   {
            printf("Error: parentheses mismatched\n");
            return false;
        }
        *outpos = sc; 
        ++outpos;
        --sl;
    }
    *outpos = 0; // Null terminator
    return true;
}
Beispiel #10
0
static bool execution_order(const TCHAR *input, double *outval)
{
    const TCHAR *strpos = input, *strend = input + _tcslen(input);
    TCHAR c, res[4];
    unsigned int sl = 0, rn = 0;
	struct calcstack stack[STACK_SIZE] = { {0, .0} }, *sc, *sc2;
	double val = 0;
	int i;
	bool ok = false;

	// While there are input tokens left
    while(strpos < strend)  {

		if (sl >= STACK_SIZE)
			return false;

               // Read the next token from input.
		c = *strpos;
                // If the token is a value or identifier
        if(is_ident(c))    {
                        // Push it onto the stack.
			stack[sl].s = chartostack (c);
            ++sl;
        }
                // Otherwise, the token is an operator  (operator here includes both operators, and functions).
        else if(is_operator(c) || is_function(c))    {
                        _stprintf(res, _T("_%02d"), rn);
                        calc_log ((_T("%s = "), res));
                        ++rn;
                        // It is known a priori that the operator takes n arguments.
                        unsigned int nargs = op_arg_count(c);
                        // If there are fewer than n values on the stack
                        if(sl < nargs) {
                                // (Error) The user has not input sufficient values in the expression.
                                return false;
                        }
                        // Else, Pop the top n values from the stack.
                        // Evaluate the operator, with the values as arguments.
                        if(is_function(c)) {
                                calc_log ((_T("%c("), c));
                                while(nargs > 0){
                                        sc = &stack[sl - nargs]; // to remove reverse order of arguments
                                        if(nargs > 1)   {
                                                calc_log ((_T("%s, "), sc));
                                        }
                                        else {
                                                calc_log ((_T("%s)\n"), sc));
                                        }
                                        --nargs;
                                }
                                sl-=op_arg_count(c);
                        }
                        else   {
                                if(nargs == 1) {
                                        sc = &stack[sl - 1];
                                        sl--;
										val = docalc1 (c, sc, val);
										calc_log ((_T("%c %s = %f;\n"), c, stacktostr(sc), val));
                               }
                                else   {
                                        sc = &stack[sl - 2];
                                        calc_log ((_T("%s %c "), stacktostr(sc), c));
                                        sc2 = &stack[sl - 1];
										val = docalc2 (c, sc, sc2);
                                         sl--;sl--;
                                        calc_log ((_T("%s = %f;\n"), stacktostr(sc2), val));
                               }
                        }
                        // Push the returned results, if any, back onto the stack.
						stack[sl].val = val;
						stack[sl].s = NULL;
            ++sl;
        }
        ++strpos;
    }
        // If there is only one value in the stack
        // That value is the result of the calculation.
        if(sl == 1) {
                sc = &stack[sl - 1];
                sl--;
				calc_log ((_T("result = %f\n"), val));
				if (outval)
					*outval = val;
				ok = true;
		}
		for (i = 0; i < STACK_SIZE; i++)
			xfree (stack[i].s);
 
		// If there are more values in the stack
        // (Error) The user input has too many values.

		return ok;
}
Beispiel #11
0
static int parse_table(HTable table, char *buf, long int *pos, int top_level)
{
    char *token=NULL;
    char *name;
    int res;

    while (1)
    {
        if (! token)
            token = read_token(buf, pos);
        if (! token)
        {
            if (top_level)
                return 0;
            else
                return -1;
        }

        if (! strcmp(token, "{"))
        {
            if (add_field_to_array(table, token, buf, pos))
            {
                free(token);
                return -1;
            }
            free(token);
            token = read_token(buf, pos);
            if (! token)
            {
                if (top_level)
                    return 0;
                else
                    return -1;
            }
            if ((! strcmp(token, ";")) || (! strcmp(token, ",")))
            {
                free(token);
                token = NULL;
            }
            continue;
        } 
        else if (! strcmp(token, "}"))
        {
            free(token);
            if (top_level)
                return -1;
            else
                return 0;
        }

        name = token;
        
        token = read_token(buf, pos);
        
        if (token && (! strcmp(token, "=")))
        {
            free(token);

            if (! is_ident(name))
            {
                free(name);
                return -1;
            }

            token = read_token(buf, pos);
            if (! token)
            {
                free(name);
                return -1;
            }

            res = add_field(table, name, token, buf, pos);
            free(name);
            free(token);
            if (res)
            {
                return -1;
            }

            token = read_token(buf, pos);
            if (! token)
            {
                if (top_level)
                    return 0;
                else
                    return -1;
            }
            if ((! strcmp(token, ";")) || (! strcmp(token, ",")))
            {
                free(token);
                token = NULL;
            }
            else
                if (strcmp(token, "}"))
                {
                    free(token);
                    return -1;
                }
        }
        else
        {
            if ((! token) && (! top_level))
            {
                free(name);
                return -1;
            }
            if (! (token && ((! strcmp(token, ";")) || (! strcmp(token, ",")) 
                        || (! strcmp(token, "}")))))
            {
                free(name);
                if (token) free(token);
                return -1;
            }

            res = add_field_to_array(table, name, buf, pos);
            free(name);
            if (res)
            {
                free(token);
                return -1;
            }

            if ((! token) || (! strcmp(token, "}")))
            {
                if (token) free(token);
                return 0;
            }

            if (token && ((! strcmp(token, ",")) || ((! strcmp(token, ";")))))
            {
                free(token);
                token = NULL;
            }
        }
    }
    
    return 0;
}
Beispiel #12
0
static obj_t parse_atom(struct Parser *st)
{
	struct token *t = next(st);
	size_t i;

	switch (t->type) {
	case DOT:
		reportlocf(st->rep, t->loc, "datum expected");
		return unspecific;
	case CPAREN:
		reportlocf(st->rep, t->loc, "unmatched parenthesis");
		return unspecific;
	case END:
		return unspecific;
	case CHAR:
		if (t->len == 2) {
			reportlocf(st->rep, t->loc,
				   "end-of-input in character literal");
			return unspecific;
		} else if (t->len == 3) {
			return make_char(t->text[2]);
		} else {
			/* Convert to lowercase */
			for (i = 0; i < t->len; i++)
				t->text[i] = tolower(t->text[i]);

			if (atom_eq("#\\space", t->text, t->len)) {
				/* Space character literal */
				return make_char(' ');
			} else if (atom_eq("#\\newline", t->text, t->len)) {
				/* Newline character literal */
				return make_char('\n');
			} else {
				reportlocf(st->rep, t->loc,
					   "illegal character literal");
				return unspecific;
			}
		}
	case ATOM:
		/* Convert to lowercase */
		for (i = 0; i < t->len; i++)
			t->text[i] = tolower(t->text[i]);

		if (atom_eq("#f", t->text, t->len)) {
			/* False constant */
			return false_obj;
		} else if (atom_eq("#t", t->text, t->len)) {
			/* True constant */
			return true_obj;
		} else if (is_number(t->text, t->len)) {
			/* Copy to buffer to make null-terminated */
			char *buf = GC_MALLOC_ATOMIC((t->len+1) * sizeof(char));
			strncpy(buf, t->text, t->len);
			buf[t->len] = 0;

			/* Convert to number */
			return make_num(atol(buf));
		} else if (is_ident(t->text, t->len)) {
			/* Symbol */
			return make_symbol(intern_string(string_from(t->text, t->len)));
		} else {
			/* Invalid atom */
			reportlocf(st->rep, t->loc, "unrecognized atom");
			return unspecific;
		}
	case STRING:
		return parse_string(st, t);
	case OARRAY:
		reportlocf(st->rep, t->loc, "array literals are not supported");
		/* fallthrough: continue processing as lists */
	case OPAREN:
		return parse_list(st);
	case QUOTE:
		return parse_quotation(S_QUOTE, st);
	case QUASIQUOTE:
		return parse_quotation(S_QUASIQUOTE, st);
	case UNQUOTE:
		return parse_quotation(S_UNQUOTE, st);
	case UNQUOTE_SPLICING:
		return parse_quotation(S_UNQUOTE_SPLICING, st);
	}

	/* We should never get to here */
	return unspecific;
}
Beispiel #13
0
bool execution_order(const char *input) {
    printf("order: (arguments in reverse order)\n");
    const char *strpos = input, *strend = input + strlen(input);
    char c, res[4];
    unsigned int sl = 0, sc, stack[32], rn = 0;
        // While there are input tokens left
    while(strpos < strend)  {
                // Read the next token from input.
        c = *strpos;
                // If the token is a value or identifier
        if(is_ident(c))    {
                        // Push it onto the stack.
            stack[sl] = c;
            ++sl;
        }
                // Otherwise, the token is an operator  (operator here includes both operators, and functions).
        else if(is_operator(c) || is_function(c))    {
                        sprintf(res, "_%02d", rn);
                        printf("%s = ", res);
                        ++rn;
                        // It is known a priori that the operator takes n arguments.
                        unsigned int nargs = op_arg_count(c);
                        // If there are fewer than n values on the stack
                        if(sl < nargs) {
                                // (Error) The user has not input sufficient values in the expression.
                                return false;
                        }
                        // Else, Pop the top n values from the stack.
                        // Evaluate the operator, with the values as arguments.
                        if(is_function(c)) {
                                printf("%c(", c);
                                while(nargs > 0)        {
                                        sc = stack[sl - 1];
                                        sl--;
                                        if(nargs > 1)   {
                                                printf("%s, ", &sc);
                                        }
                                        else {
                                                printf("%s)\n", &sc);
                                        }
                                        --nargs;
                                }
                        }
                        else   {
                                if(nargs == 1) {
                                        sc = stack[sl - 1];
                                        sl--;
                                        printf("%c %s;\n", c, &sc);
                                }
                                else   {
                                        sc = stack[sl - 1];
                                        sl--;
                                        printf("%s %c ", &sc, c);
                                        sc = stack[sl - 1];
                                        sl--;
                                        printf("%s;\n",&sc);
                                }
                        }
                        // Push the returned results, if any, back onto the stack.
            stack[sl] = *(unsigned int*)res;
            ++sl;
        }
        ++strpos;
    }
        // If there is only one value in the stack
        // That value is the result of the calculation.
        if(sl == 1) {
                sc = stack[sl - 1];
                sl--;
                printf("%s is a result\n", &sc);
                return true;
        }
        // If there are more values in the stack
        // (Error) The user input has too many values.
        return false;
}
Beispiel #14
0
int main(int argc, char *argv[])
{
	int i, k, t;
	u8 *test_mat, *save_mat, *invr_mat;

	u8 test1[] = { 1, 1, 6,
		1, 1, 1,
		7, 1, 9
	};

	u8 test2[] = { 0, 1, 6,
		1, 0, 1,
		0, 1, 9
	};

	u8 test3[] = { 0, 0, 1,
		1, 0, 0,
		0, 1, 1
	};

	u8 test4[] = { 0, 1, 6, 7,
		1, 1, 0, 0,
		0, 1, 2, 3,
		3, 2, 2, 3
	};			// = row3+3*row2

	printf("gf_inverse_test: max=%d ", KMAX);

	test_mat = malloc(KMAX * KMAX);
	save_mat = malloc(KMAX * KMAX);
	invr_mat = malloc(KMAX * KMAX);

	if (NULL == test_mat || NULL == save_mat || NULL == invr_mat)
		return -1;

	// Test with lots of leading 1's
	k = 3;
	memcpy(test_mat, test1, k * k);
	if (inv_test(test_mat, invr_mat, save_mat, k))
		return -1;

	// Test with leading zeros
	k = 3;
	memcpy(test_mat, test2, k * k);
	if (inv_test(test_mat, invr_mat, save_mat, k))
		return -1;

	// Test 3
	k = 3;
	memcpy(test_mat, test3, k * k);
	if (inv_test(test_mat, invr_mat, save_mat, k))
		return -1;

	// Test 4 - try a singular matrix
	k = 4;
	memcpy(test_mat, test4, k * k);
	if (!gf_invert_matrix(test_mat, invr_mat, k)) {
		printf("Fail: didn't catch singular matrix\n");
		print_matrix(test4, 4);
		return -1;
	}
	// Do random test of size KMAX
	k = KMAX;

	for (i = 0; i < k * k; i++)
		test_mat[i] = save_mat[i] = rand();

	if (gf_invert_matrix(test_mat, invr_mat, k)) {
		printf("rand picked a singular matrix, try again\n");
		return -1;
	}

	matrix_mult(invr_mat, save_mat, test_mat, k);

	if (is_ident(test_mat, k)) {
		printf("fail\n");
		print_matrix(save_mat, k);
		print_matrix(invr_mat, k);
		print_matrix(test_mat, k);
		return -1;
	}
	// Do Randoms.  Random size and coefficients
	for (t = 0; t < RANDOMS; t++) {
		k = rand() % KMAX;

		for (i = 0; i < k * k; i++)
			test_mat[i] = save_mat[i] = rand();

		if (gf_invert_matrix(test_mat, invr_mat, k))
			continue;

		matrix_mult(invr_mat, save_mat, test_mat, k);

		if (is_ident(test_mat, k)) {
			printf("fail rand k=%d\n", k);
			print_matrix(save_mat, k);
			print_matrix(invr_mat, k);
			print_matrix(test_mat, k);
			return -1;
		}
		if (0 == (t % 8))
			putchar('.');
	}

	printf(" Pass\n");
	return 0;
}
bool shunting_yard(const char *input, char *output)
{
    const char *strpos = input, *strend = input + strlen(input);
    char c, *outpos = output;

    char stack[512];       // operator stack
    unsigned int sl = 0;  // stack length
    char     sc;          // used for record stack element

    while(strpos < strend)   {
        // read one token from the input stream
        c = *strpos;
        if(c != ' ')    {
            // If the token is a number (identifier), then add it to the output queue.
            if(is_ident(c))  {
                *outpos = c; ++outpos;
            }
            // If the token is a function token, then push it onto the stack.
            else if(is_function(c))   {
                stack[sl] = c;
                ++sl;
            }
            // If the token is a function argument separator (e.g., a comma):
            else if(c == ',')   {
                bool pe = false;
                while(sl > 0)   {
                    sc = stack[sl - 1];
                    if(sc == '(')  {
                        pe = true;
                        break;
                    }
                    else  {
                        // Until the token at the top of the stack is a left parenthesis,
                        // pop operators off the stack onto the output queue.
                        *outpos = sc;
                        ++outpos;
                        sl--;
                    }
                }
                // If no left parentheses are encountered, either the separator was misplaced
                // or parentheses were mismatched.
                if(!pe)   {
                    printf("Error: separator or parentheses mismatched\n");
                    return false;
                }
            }
            // If the token is an operator, op1, then:
            else if(is_operator(c))  {
                while(sl > 0)    {
                    sc = stack[sl - 1];
                    if(is_operator(sc) &&
                        ((op_left_assoc(c) && (op_preced(c) >= op_preced(sc))) ||
                           (op_preced(c) > op_preced(sc))))   {
                        // Pop op2 off the stack, onto the output queue;
                        *outpos = sc;
                        ++outpos;
                        sl--;
                    }
                    else   {
                        break;
                    }
                }
                // push op1 onto the stack.
                stack[sl] = c;
                ++sl;
            }
            // If the token is a left parenthesis, then push it onto the stack.
            else if(c == '(')   {
                stack[sl] = c;
                ++sl;
            }
            // If the token is a right parenthesis:
            else if(c == ')')    {
                bool pe = false;
                // Until the token at the top of the stack is a left parenthesis,
                // pop operators off the stack onto the output queue
                while(sl > 0)     {
                    sc = stack[sl - 1];
                    if(sc == '(')    {
                        pe = true;
                        break;
                    }
                    else  {
                        *outpos = sc;
                        ++outpos;
                        sl--;
                    }
                }
                // If the stack runs out without finding a left parenthesis, then there are mismatched parentheses.
                if(!pe)  {
                    printf("Error: parentheses mismatched\n");

                    return false;
                }
                // Pop the left parenthesis from the stack, but not onto the output queue.
                sl--;
                // If the token at the top of the stack is a function token, pop it onto the output queue.
                if(sl > 0)   {
                    sc = stack[sl - 1];
                    if(is_function(sc))   {
                        *outpos = sc;
                        ++outpos;
                        sl--;
                    }
                }
            }
            else  {
                printf("Unknown token <%c>\n", c);
                return false; // Unknown token
            }
        }
        ++strpos;
    }
    // When there are no more tokens to read:
    // While there are still operator tokens in the stack:
    while(sl > 0)  {
        sc = stack[sl - 1];
        if(sc == '(' || sc == ')')   {
            printf("Error: parentheses mismatched\n");
            return false;
        }
        *outpos = sc;
        ++outpos;
        --sl;
    }
    *outpos = 0; // Null terminator
    return true;
}