コード例 #1
0
ファイル: parse.c プロジェクト: PoCTo/yamsh
void ParseMorpheme(char* S, ParseStates* state, Tree** T){
    static char* redirop=NULL;
    redirop=myrealloc(redirop,3*sizeof(char));
    Tree* newT=NULL;
    switch (*state){
        case CMD:{
            switch (ParseGetTokenClass(S)){
                case TEXT:
                    StringPut(&((*T)->cmd),S);
                    (*T)->type=LINK_COMMAND;
                    *state=ARGS;
                    break;
                case SUBSHELL_BEGIN:
                    newT=TreeInit();
                    newT->type=LINK_SUBSHELL;
                    newT->left=(*T);
                    newT->parent=(*T)->parent;
                    (*T)->parent=newT;
                    if (newT->parent!=NULL){
                        if (newT->parent->left==(*T)) newT->parent->left=newT;
                        if (newT->parent->right==(*T)) newT->parent->right=newT;
                    }
                    *state=CMD;
                    break;
                case SUBSHELL_END:
                    while((*T)!=NULL &&((*T)->type!=LINK_SUBSHELL)) *T=(*T)->parent;
                    if (*T==NULL) *state=PARSEERROR;
                    else *state=AFTERSUBSHELL;
                    break;
                default:
                    *state=PARSEERROR;
                    break;
            }
            break;
        }
        case ARGS:{
            switch (ParseGetTokenClass(S)){
                case TEXT:
                    ListAdd(&((*T)->args),S);
                    *state=ARGS;
                    break;
                case REDIRECT:
                    strcpy(redirop,S);
                    *state=REDIR;
                    break;
                case OPER:
                    newT=TreeInit();
                    newT->type=OperatorType(S);
                    if (newT->type==LINK_AND || newT->type==LINK_OR){
                        while ((*T)->parent->type!=LINK_SUBSHELL) (*T)=(*T)->parent;
                    }
                    if (newT->type==LINK_BACKGROUND || newT->type==LINK_SEMICOLON){
                        while ((*T)->parent->type!=LINK_SUBSHELL
                                && (*T)->parent->type!=LINK_AND
                                && (*T)->parent->type!=LINK_OR) (*T)=(*T)->parent;
                    }
                    if (newT->type==LINK_BACKGROUND || newT->type==LINK_SEMICOLON){
                        while ((*T)->parent->type!=LINK_SUBSHELL
                                && (*T)->parent->type!=LINK_AND
                                && (*T)->parent->type!=LINK_OR) (*T)=(*T)->parent;
                    }
                    newT->parent=(*T)->parent;
                    if (newT->parent!=NULL) {
                        if (newT->parent->left==(*T)) newT->parent->left=newT;
                        if (newT->parent->right==(*T)) newT->parent->right=newT;
                    }
                    (*T)->parent=newT;
                    newT->left=(*T);
                    newT->right=TreeInit();
                    newT->right->parent=newT;
                    *T=newT->right;
                    *state=CMD;
                    break;
                case SUBSHELL_END:
                    while((*T)!=NULL &&((*T)->type!=LINK_SUBSHELL)) *T=(*T)->parent;
                    if (*T==NULL) *state=PARSEERROR;
                    else *state=AFTERSUBSHELL;
                    break;
                default:
                    *state=PARSEERROR;
            }
            break;
        }
        case REDIR:{
            switch (ParseGetTokenClass(S)){
                case TEXT:
                    if (!strcmp(redirop,">")) StringPut(&((*T)->out),S);
                    if (!strcmp(redirop,">>")) StringPut(&((*T)->append),S);
                    if (!strcmp(redirop,"<")) StringPut(&((*T)->in),S);
                    *state=ARGS;
                    break;
                default:
                    *state=PARSEERROR;
            }
            break;
        }
        case AFTERSUBSHELL:{
            switch (ParseGetTokenClass(S)){
                case OPER:
                    newT=TreeInit();
                    newT->type=OperatorType(S);
                    if (newT->type==LINK_AND || newT->type==LINK_OR){
                        while ((*T)->parent->type!=LINK_SUBSHELL) (*T)=(*T)->parent;
                    }
                    if (newT->type==LINK_BACKGROUND || newT->type==LINK_SEMICOLON){
                        while ((*T)->parent->type!=LINK_SUBSHELL
                                && (*T)->parent->type!=LINK_AND
                                && (*T)->parent->type!=LINK_OR) (*T)=(*T)->parent;
                    }
                    if (newT->type==LINK_BACKGROUND || newT->type==LINK_SEMICOLON){
                        while ((*T)->parent->type!=LINK_SUBSHELL
                                && (*T)->parent->type!=LINK_AND
                                && (*T)->parent->type!=LINK_OR) (*T)=(*T)->parent;
                    }
                    newT->parent=(*T)->parent;
                    if (newT->parent!=NULL) {
                        if (newT->parent->left==(*T)) newT->parent->left=newT;
                        if (newT->parent->right==(*T)) newT->parent->right=newT;
                    }
                    (*T)->parent=newT;
                    newT->left=(*T);
                    newT->right=TreeInit();
                    newT->right->parent=newT;
                    *T=newT->right;
                    *state=CMD;
                    break;
                case REDIRECT:
                    *state=REDIR;
                    break;
                case SUBSHELL_END:
                    *T=(*T)->parent;
                    while((*T)!=NULL &&((*T)->type!=LINK_SUBSHELL)) *T=(*T)->parent;
                    if (*T==NULL) *state=PARSEERROR;
                    else *state=AFTERSUBSHELL;
                    break;
                default:
                    *state=PARSEERROR;
            }
            break;
        }
        default:
            *state=PARSEERROR;
    }
}
コード例 #2
0
ファイル: edit-sgml.c プロジェクト: Ionic/nx-libs
static void
DoReplace (FILE *f, ReplaceSet *s)
{
    int		c;
    String	*tag;
    Replace	*r;
    SkipStack	*ss = 0;
    LoopStack	*ls = 0;
    int		skipping = 0;

    while ((c = getc (f)) != EOF)
    {
	if (c == '@')
	{
	    tag = StringNew ();
	    while ((c = getc (f)) != '@')
	    {
		if (c == EOF)
		    abort ();
		StringAdd (tag, c);
	    }
	    if (ls)
		StringAddString (tag, ls->extra->buf);
	    switch (tag->buf[0]) {
	    case '?':
		ss = SkipStackPush (ss, skipping);
		if (!ReplaceSetFind (s, tag->buf + 1))
		    skipping++;
		LineSkip (f);
		break;
	    case ':':
		if (!ss)
		    abort ();
		if (ss->skipping == skipping)
		    ++skipping;
		else
		    --skipping;
		LineSkip (f);
		break;
	    case ';':
		skipping = ss->skipping;
		ss = SkipStackPop (ss);
		LineSkip (f);
		break;
	    case '{':
		ls = LoopStackPush (ls, f, tag->buf + 1);
		LineSkip (f);
		break;
	    case '}':
		ls = LoopStackLoop (s, ls, f);
		LineSkip (f);
		break;
	    default:
		r = ReplaceSetFind (s, tag->buf);
		if (r && !skipping)
		    StringPut (stdout, r->text);
		break;
	    }
	    StringDispose (tag);
	}
	else if (!skipping)
	    putchar (c);
    }
}