Пример #1
0
void factor()					/* 式の因子のコンパイル */
{
	int tIndex, i;
	KeyId k;
	if (token.kind==Id){
		tIndex = searchT(token.u.id, varId);
		setIdKind(k=kindT(tIndex));			/* 印字のための情報のセット */
		switch (k) {
		case varId: case parId:			/* 変数名かパラメタ名 */
			genCodeT(lod, tIndex);
			token = nextToken(); break;
		case constId:					/* 定数名 */
			genCodeV(lit, val(tIndex));
			token = nextToken(); break;
		case funcId:					/* 関数呼び出し */
			token = nextToken();
			if (token.kind==Lparen){
				i=0; 					/* iは実引数の個数 */
				token = nextToken();
				if (token.kind != Rparen) {
					for (; ; ) {
						expression(); i++;	/* 実引数のコンパイル */
						if (token.kind==Comma){	/* 次がコンマなら実引数が続く */
							token = nextToken();
							continue;
						}
						token = checkGet(token, Rparen);
						break;
					}
				} else
					token = nextToken();
				if (pars(tIndex) != i) 
					errorMessage("\\#par");	/* pars(tIndex)は仮引数の個数 */
			}else{
				errorInsert(Lparen);
				errorInsert(Rparen);
			}
			genCodeT(cal, tIndex);				/* call命令 */
			break;
		}
	}else if (token.kind==Num){			/* 定数 */
		genCodeV(lit, token.u.value);
		token = nextToken();
	}else if (token.kind==Lparen){			/* 「(」「因子」「)」 */
		token = nextToken();
		expression();
		token = checkGet(token, Rparen);
	}
	switch (token.kind){					/* 因子の後がまた因子ならエラー */
	case Id: case Num: case Lparen:
		errorMissingOp();
		factor();
	default:
		return;
	}	
}
Пример #2
0
Файл: lzw.c Проект: krishpop/LZW
// encodes the input stream by taking advantage of lzw algorithm
// also implements logic to prune the trie structure used to store the string
// table, and escapes single character codes
void encode(int e, int m, int p) {
    Trie st;
    createT(&st, e);
    int c = EMPTY;                    // same as (EMPTY, K), index of the prefix

    // int value of char k we are testing to see if c,k exists in the table
    int k;

    // number of codes you have inserted, 256 without escape flag...
    int codeCount = (e) ? 3 : 259;
    int bitCount = (e) ? 2 : 9;
    int maxbits = (m<=8 || m>20) ? 12 : m;
    int maxcodes = (1 << maxbits);
    int firstRead = false;   // if first read of k when e flag is present

    int pruneCount = 0;

    printf("%02d:%d:%d:", maxbits, p, e);
    while((k = getchar())!= EOF) {
        st[c].appearances++;
        int ck = searchT(&st, c, k, e);    // will increment c's appearance once

        // if ck is not in the table
        if(ck<0) {
            // if prune flag & reached maxcodes, do a prune before next insert
            // into the table, putBits 0 to indicate a prune has occurred
            // a prune should likewise happen in decode
            if(c!=EMPTY) {
                putBits(bitCount, c);
            }
            // add ck to the table as long as (e && c == EMPTY) is false
            // we will add (empty, k) to the table after this condition
            // !e and c==EMPTY will never happen, bc all chars will have been
            // added as children to empty

            // prune right before we reach maxcodes, we would have lost the next
            // code we insert anyways, now we won't lose k
            if(p&&(codeCount+1==maxcodes)) {
                putBits(bitCount, 0);
                pruneCount++;
                Trie newst;
                createT(&newst, e);
                int oldCodeCount = codeCount;
                codeCount=pruneT(&st, &newst, e, oldCodeCount);
                destroyT(&st, oldCodeCount);
                st = newst;
                bitCount=codeLength(codeCount);
                c=EMPTY;
                ungetc(k, stdin);
                continue;
            }
            //
            if(!e || c!=EMPTY) {
                if(codeCount<maxcodes) {
                    if(tableFilled(codeCount+1)) {
                        int newSize = (codeCount+1)*2;
                        expandT(&st, newSize);
                        bitCount++;
                    }
                    addT(&st, c, k, codeCount);
                    codeCount++;
                }
            }
            // if escape flag is on and k is not yet added to the table
            if(e && searchT(&st, EMPTY, k, e) < 0) {
                putBits(bitCount, ESC); // 1 is the index of escape character
                putBits(8, k);
                if(codeCount<maxcodes) {
                    if(codeLength(codeCount+1)-codeLength(codeCount)) {
                        int newSize = (codeCount+1)*2;
                        expandT(&st, newSize);
                        bitCount++;
                    }
                    addT(&st, EMPTY, k, codeCount);
                    codeCount++;
                }
                firstRead=true; // encode escaped something, don't unget(k)
                // if this happens
            }

            c = EMPTY; // make c empty again
            if(!firstRead) {
                ungetc(k, stdin);   // put k back to start reading
            }
            // a new character
            else {
                firstRead = false;
            }
        }
        else {
            c=ck; // set c to index of next code
        }
    }


    if(c!=EMPTY) {
        putBits(bitCount, c);
    }

    putBits(bitCount, EOFILE);   // puts EOF
    flushBits();
    destroyT(&st, codeCount);
}
Пример #3
0
void statement()			/* 文のコンパイル */
{
	int tIndex;
	KindT k;
	int backP, backP2;				/* バックパッチ用 */

	while(1) {
		switch (token.kind) {
		case Id:					/* 代入文のコンパイル */
			tIndex = searchT(token.u.id, varId);	/* 左辺の変数のインデックス */
			setIdKind(k=kindT(tIndex));			/* 印字のための情報のセット */
			if (k != varId && k != parId) 		/* 変数名かパラメタ名のはず */
				errorType("var/par");
			token = checkGet(nextToken(), Assign);			/* ":="のはず */
			expression();					/* 式のコンパイル */
			genCodeT(sto, tIndex);				/* 左辺への代入命令 */
			return;
		case If:					/* if文のコンパイル */
			token = nextToken();
			condition();					/* 条件式のコンパイル */
			token = checkGet(token, Then);		/* "then"のはず */
			backP = genCodeV(jpc, 0);			/* jpc命令 */
			statement();					/* 文のコンパイル */
			backPatch(backP);				/* 上のjpc命令にバックパッチ */
			return;
		case Ret:					/* return文のコンパイル */
			token = nextToken();
			expression();					/* 式のコンパイル */
			genCodeR();					/* ret命令 */
			return;
		case Begin:				/* begin . . end文のコンパイル */
			token = nextToken();
			while(1){
				statement();				/* 文のコンパイル */
				while(1){
					if (token.kind==Semicolon){		/* 次が";"なら文が続く */
						token = nextToken();
						break;
					}
					if (token.kind==End){			/* 次がendなら終り */
						token = nextToken();
						return;
					}
					if (isStBeginKey(token)){		/* 次が文の先頭記号なら */
						errorInsert(Semicolon);	/* ";"を忘れたことにする */
						break;
					}
					errorDelete();	/* それ以外ならエラーとして読み捨てる */
					token = nextToken();
				}
			}
		case While:				/* while文のコンパイル */
			token = nextToken();
			backP2 = nextCode();			/* while文の最後のjmp命令の飛び先 */
			condition();				/* 条件式のコンパイル */
			token = checkGet(token, Do);	/* "do"のはず */
			backP = genCodeV(jpc, 0);		/* 条件式が偽のとき飛び出すjpc命令 */
			statement();				/* 文のコンパイル */
			genCodeV(jmp, backP2);		/* while文の先頭へのジャンプ命令 */
			backPatch(backP);	/* 偽のとき飛び出すjpc命令へのバックパッチ */
			return;
		case Write:			/* write文のコンパイル */
			token = nextToken();
			expression();				/* 式のコンパイル */
			genCodeO(wrt);				/* その値を出力するwrt命令 */
			return;
		case WriteLn:			/* writeln文のコンパイル */
			token = nextToken();
			genCodeO(wrl);				/* 改行を出力するwrl命令 */
			return;
		case End: case Semicolon:			/* 空文を読んだことにして終り */
			return;
		default:				/* 文の先頭のキーまで読み捨てる */
			errorDelete();				/* 今読んだトークンを読み捨てる */
			token = nextToken();
			continue;
		}		
	}
}
Пример #4
0
/* RubikSq.c | Stephen Krewson | CPSC 223b. USAGE: RubikSq [-r] [HEIGHT WIDTH]
MAXLENGTH INITIAL GOAL. RubikSq solves a Rubik's square puzzle using a trie data
structure and breadth-first search to find the fewest number of moves necessary
to transform INITIAL into GOAL.
*/
int main (int argc, char *argv[])
{									// 1. PARSING COMMAND-LINE ARGS
	bool rFlag = false;
	int maxLength = 0; 
	int pos = 0;					// pos is counter for moving through argv[]
	int height = 3, width = 3;		// default values
	char *initial = NULL;
	char *goal = NULL;
	
	if (argc % 2 != 0)				// "-r" specified				
	{
		if (argc > 3)
		{
			if (strcmp(argv[1], "-r") != 0)
				KILL("ERROR: '-r' flag improperly specified.");
			else
				rFlag = true;
		}
		else
		 KILL("ERROR: Insufficient number of arguments.");
	}
	if (argc == 6 || argc == 7)		// HEIGHT and WIDTH specified
	{								// Indexes depend on -r flag
		pos = (rFlag == true) ? 2 : 1;
		
		initial = strdup(argv[pos+3]);	// use malloc bc we will call free()
		goal = strdup(argv[pos+4]);		// on all the dict nodes
	
		if (!(height = atoi(argv[pos]))  || 
			!(width = atoi(argv[pos+1])) ||
			(height < 2 || height > 5)	 ||
			(width < 2 || width > 5))
			KILL("ERROR: Invalid HEIGHT and WIDTH values.");

		char *endPtr;	
		maxLength = (int) strtol(argv[pos+2], &endPtr, 10);
		
		if (endPtr < argv[pos+2] + strlen(argv[pos+2]))
			KILL("ERROR: MAXLENGTH contains nun-numeric characters.");
		else if (maxLength < 0)
			KILL ("ERROR: MAXLENGTH is negative.");

		if (!checkTray(height, width, initial, goal))
			KILL("ERROR: Invalid tray sequences.");
	
	}								// HEIGHT, WIDTH NOT specified
	else if (argc == 4 || argc == 5)
	{
		pos = (rFlag == true) ? 2 : 1;
		
		initial = strdup(argv[pos+1]);
		goal = strdup(argv[pos+2]);

		char *endPtr;	
		maxLength = (int) strtol(argv[pos], &endPtr, 10);
		
		if (endPtr < argv[pos] + strlen(argv[pos]))
			KILL("ERROR: MAXLENGTH contains nun-numeric characters.");
		else if (maxLength < 0)
			KILL ("ERROR: MAXLENGTH is negative.");

		if (!checkTray(height, width, initial, goal))
			KILL("ERROR: Invalid tray sequences.");
	}
	else
	{
		KILL("ERROR: Invalid number of  arguments.");
	}
	Trie dict;						// Initialize trie data structure
	createT(&dict);
	Stack stk1, stk2;				// Initialize the "queue"
	createS(&stk1);
	createS(&stk2);
		
	char *currentPos = NULL;		// pointer for position being processed
	char *prevPos = NULL;	     	// pointer to "from" attr in the dict
	long lengthPos = 0;				// address to hold "length" attr in the dict
	int permutations = 0;	    	// hold # of permutations getPerms returns

	insertT(&dict, goal, NULL, 0);				// Add GOAL to dictionary
	enqueue(&stk1, &stk2, goal);				// push GOAL onto the queue
	
	while (!isEmptyQ(&stk1, &stk2))				// While the queue is not empty
	{
		dequeue(&stk1, &stk2, &currentPos);		// Remove P from head of queue
		searchT(&dict, currentPos, &prevPos, &lengthPos);
												// lengPos holds length of P
		if (lengthPos + 2 < maxLength)			// +2 because currentPos is 1
		{							// more than the previous distance and each
									// permutation is another distance of 1
			char **perms;			// array of pointers to permutations of P
			perms = getPerms(currentPos, height, width, rFlag, &permutations);
			
			for (int j = 0; j < permutations; j++)	// for each position . . .
			{
				if (strcmp(initial, perms[j]) == 0)	// if P' is the INITIAL
				{									// add it so we can trace
					insertT(&dict, perms[j], currentPos, lengthPos+1);

					printf("%s\n", initial);	// print INITIAL
					printf("%s\n", currentPos);	// reached INITIAL from...
					
					char *holder2;				// follow path of search
					holder2 = currentPos;		// start at currentPos

					while (strcmp(holder2, goal) != 0)
					{
						if(!searchT(&dict, currentPos, &holder2, &lengthPos)) 
						{
							KILL("ERROR: searchT() failed.");
						}
						printf("%s\n", holder2);
						currentPos = holder2;
					}

					destroyS(&stk1);			// get rid of the queue
					destroyS(&stk2);
					deleteT(dict, dict);
					free(dict);					// Remember root node
					
					free(perms[j]);
					free(perms);				// free the pointer array

					exit(0);					// Successful exit!
				}											
				else if (!searchT(&dict, perms[j], &prevPos, &lengthPos))
				{								// Put p' in dict, on queue
					if (!insertT(&dict, perms[j], currentPos, lengthPos+1)) 
					{
						KILL("ERROR: insertT() failed.");
					}
					enqueue(&stk1, &stk2, perms[j]);
				}
				else				// else P' is already in the dictionary
				{
					free(perms[j]);	// don't need it anymore!
				}
			}
			free(perms);			// Free the pointer array
		}
	}
	
	destroyS(&stk1);				// Cleanup in case of no valid sequence
	destroyS(&stk2);
	deleteT(dict, dict);
	free(dict);						// Remember to clean root node of dict

	return EXIT_SUCCESS;
}