⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parse_noyacc.c

📁 nedit 是一款linux下的开发源码的功能强大的编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
*/Program *ParseMacro(char *expr, char **msg, char **stoppedAt){    Program *prog;    BeginCreatingProgram();    /* call yyparse to parse the string and check for success.  If the parse       failed, return the error message and string index (the grammar aborts       parsing at the first error) */    InPtr = expr;    if (yyparse()) {        *msg = ErrMsg;        *stoppedAt = InPtr;        FreeProgram(FinishCreatingProgram());        return NULL;    }    /* get the newly created program */    prog = FinishCreatingProgram();    /* parse succeeded */    *msg = "";    *stoppedAt = InPtr;    return prog;}static int yylex(void){    int i, len;    Symbol *s;    static DataValue value = {NO_TAG, {0}};    static char escape[] = "\\\"ntbrfav";    static char replace[] = "\\\"\n\t\b\r\f\a\v";    /* skip whitespace, backslash-newline combinations, and comments, which are       all considered whitespace */    for (;;) {        if (*InPtr == '\\' && *(InPtr + 1) == '\n')            InPtr += 2;        else if (*InPtr == ' ' || *InPtr == '\t')            InPtr++;        else if (*InPtr == '#')            while (*InPtr != '\n' && *InPtr != '\0') {                /* Comments stop at escaped newlines */                if (*InPtr == '\\' && *(InPtr + 1) == '\n') {                    InPtr += 2;                    break;                }                InPtr++;            }        else            break;    }    /* return end of input at the end of the string */    if (*InPtr == '\0') {        return 0;    }    /* process number tokens */    if (isdigit((unsigned char)*InPtr))  { /* number */        char name[28];        sscanf(InPtr, "%d%n", &value.val.n, &len);        sprintf(name, "const %d", value.val.n);        InPtr += len;        value.tag = INT_TAG;        if ((yylval.sym=LookupSymbol(name)) == NULL)            yylval.sym = InstallSymbol(name, CONST_SYM, value);        return NUMBER;    }    /* process symbol tokens.  "define" is a special case not handled       by this parser, considered end of input.  Another special case       is action routine names which are allowed to contain '-' despite       the ambiguity, handled in matchesActionRoutine. */    if (isalpha((unsigned char)*InPtr) || *InPtr == '$') {        if ((s=matchesActionRoutine(&InPtr)) == NULL) {            char symName[MAX_SYM_LEN+1], *p = symName;            *p++ = *InPtr++;            while (isalnum((unsigned char)*InPtr) || *InPtr=='_') {                if (p >= symName + MAX_SYM_LEN)                    InPtr++;                else                    *p++ = *InPtr++;            }            *p = '\0';            if (!strcmp(symName, "while")) return WHILE;            if (!strcmp(symName, "if")) return IF;            if (!strcmp(symName, "else")) return ELSE;            if (!strcmp(symName, "for")) return FOR;            if (!strcmp(symName, "break")) return BREAK;            if (!strcmp(symName, "continue")) return CONTINUE;            if (!strcmp(symName, "return")) return RETURN;        if (!strcmp(symName, "in")) return IN;        if (!strcmp(symName, "delete") && follow_non_whitespace('(', SYMBOL, DELETE) == DELETE) return DELETE;            if (!strcmp(symName, "define")) {                InPtr -= 6;                return 0;            }            if ((s=LookupSymbol(symName)) == NULL) {                s = InstallSymbol(symName, symName[0]=='$' ?                        (isdigit((unsigned char)symName[1]) ?                        ARG_SYM : GLOBAL_SYM) : LOCAL_SYM, value);                s->value.tag = NO_TAG;            }        }        yylval.sym = s;        return SYMBOL;    }    /* process quoted strings w/ embedded escape sequences */    if (*InPtr == '\"') {        char string[MAX_STRING_CONST_LEN], *p = string;        InPtr++;        while (*InPtr != '\0' && *InPtr != '\"' && *InPtr != '\n') {            if (p >= string + MAX_STRING_CONST_LEN) {                InPtr++;                continue;            }            if (*InPtr == '\\') {                InPtr++;                if (*InPtr == '\n') {                    InPtr++;                    continue;                }                for (i=0; escape[i]!='\0'; i++) {                    if (escape[i] == '\0') {                        *p++= *InPtr++;                        break;                    } else if (escape[i] == *InPtr) {                        *p++ = replace[i];                        InPtr++;                        break;                    }                }            } else                *p++= *InPtr++;        }        *p = '\0';        InPtr++;        yylval.sym = InstallStringConstSymbol(string);        return STRING;    }    /* process remaining two character tokens or return single char as token */    switch(*InPtr++) {    case '>':   return follow('=', GE, GT);    case '<':   return follow('=', LE, LT);    case '=':   return follow('=', EQ, '=');    case '!':   return follow('=', NE, NOT);    case '+':   return follow2('+', INCR, '=', ADDEQ, '+');    case '-':   return follow2('-', DECR, '=', SUBEQ, '-');    case '|':   return follow2('|', OR, '=', OREQ, '|');    case '&':   return follow2('&', AND, '=', ANDEQ, '&');    case '*':   return follow2('*', POW, '=', MULEQ, '*');    case '/':   return follow('=', DIVEQ, '/');    case '%':   return follow('=', MODEQ, '%');    case '^':   return POW;    default:    return *(InPtr-1);    }}/*** look ahead for >=, etc.*/static int follow(char expect, int yes, int no){    if (*InPtr++ == expect)        return yes;    InPtr--;    return no;}static int follow2(char expect1, int yes1, char expect2, int yes2, int no){    char next = *InPtr++;    if (next == expect1)        return yes1;    if (next == expect2)        return yes2;    InPtr--;    return no;}static int follow_non_whitespace(char expect, int yes, int no){    char *localInPtr = InPtr;    while (1) {        if (*localInPtr == ' ' || *localInPtr == '\t') {            ++localInPtr;        }        else if (*localInPtr == '\\' && *(localInPtr + 1) == '\n') {            localInPtr += 2;        }        else if (*localInPtr == expect) {            return(yes);        }        else {            return(no);        }    }}/*** Look (way) ahead for hyphenated routine names which begin at inPtr.  A** hyphenated name is allowed if it is pre-defined in the global symbol** table.  If a matching name exists, returns the symbol, and update "inPtr".**** I know this is horrible language design, but existing nedit action routine** names contain hyphens.  Handling them here in the lexical analysis process** is much easier than trying to deal with it in the parser itself.  (sorry)*/static Symbol *matchesActionRoutine(char **inPtr){    char *c, *symPtr;    int hasDash = False;    char symbolName[MAX_SYM_LEN+1];    Symbol *s;    symPtr = symbolName;    for (c = *inPtr; isalnum((unsigned char)*c) || *c=='_' ||            ( *c=='-' && isalnum((unsigned char)(*(c+1)))); c++) {        if (*c == '-')            hasDash = True;        *symPtr++ = *c;    }    if (!hasDash)        return NULL;    *symPtr = '\0';    s = LookupSymbol(symbolName);    if (s != NULL)        *inPtr = c;    return s;}/*** Called by yacc to report errors (just stores for returning when** parsing is aborted.  The error token action is to immediate abort** parsing, so this message is immediately reported to the caller** of ParseExpr)*/static int yyerror(char *s){    ErrMsg = s;    return 0;}#line 965 "y.tab.c"/* allocate initial stack or double stack size, up to YYMAXDEPTH */static int yygrowstack(){    int newsize, i;    short *newss;    YYSTYPE *newvs;    if ((newsize = yystacksize) == 0)        newsize = YYINITSTACKSIZE;    else if (newsize >= YYMAXDEPTH)        return -1;    else if ((newsize *= 2) > YYMAXDEPTH)        newsize = YYMAXDEPTH;    i = yyssp - yyss;    newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) :      (short *)malloc(newsize * sizeof *newss);    if (newss == NULL)        return -1;    yyss = newss;    yyssp = newss + i;    newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) :      (YYSTYPE *)malloc(newsize * sizeof *newvs);    if (newvs == NULL)        return -1;    yyvs = newvs;    yyvsp = newvs + i;    yystacksize = newsize;    yysslim = yyss + newsize - 1;    return 0;}#define YYABORT goto yyabort#define YYREJECT goto yyabort#define YYACCEPT goto yyaccept#define YYERROR goto yyerrlab#ifndef YYPARSE_PARAM#if defined(__cplusplus) || __STDC__#define YYPARSE_PARAM_ARG void#define YYPARSE_PARAM_DECL#else	/* ! ANSI-C/C++ */#define YYPARSE_PARAM_ARG#define YYPARSE_PARAM_DECL#endif	/* ANSI-C/C++ */#else	/* YYPARSE_PARAM */#ifndef YYPARSE_PARAM_TYPE#define YYPARSE_PARAM_TYPE void *#endif#if defined(__cplusplus) || __STDC__#define YYPARSE_PARAM_ARG YYPARSE_PARAM_TYPE YYPARSE_PARAM#define YYPARSE_PARAM_DECL#else	/* ! ANSI-C/C++ */#define YYPARSE_PARAM_ARG YYPARSE_PARAM#define YYPARSE_PARAM_DECL YYPARSE_PARAM_TYPE YYPARSE_PARAM;#endif	/* ANSI-C/C++ */#endif	/* ! YYPARSE_PARAM */intyyparse (YYPARSE_PARAM_ARG)    YYPARSE_PARAM_DECL{    register int yym, yyn, yystate;#if YYDEBUG    register const char *yys;    if ((yys = getenv("YYDEBUG")))    {        yyn = *yys;        if (yyn >= '0' && yyn <= '9')            yydebug = yyn - '0';    }#endif    yynerrs = 0;    yyerrflag = 0;    yychar = (-1);    if (yyss == NULL && yygrowstack()) goto yyoverflow;    yyssp = yyss;    yyvsp = yyvs;    *yyssp = yystate = 0;yyloop:    if ((yyn = yydefred[yystate])) goto yyreduce;    if (yychar < 0)    {        if ((yychar = yylex()) < 0) yychar = 0;#if YYDEBUG        if (yydebug)        {            yys = 0;            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];            if (!yys) yys = "illegal-symbol";            printf("%sdebug: state %d, reading %d (%s)\n",                    YYPREFIX, yystate, yychar, yys);        }#endif    }    if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)    {#if YYDEBUG        if (yydebug)            printf("%sdebug: state %d, shifting to state %d\n",                    YYPREFIX, yystate, yytable[yyn]);#endif        if (yyssp >= yysslim && yygrowstack())        {            goto yyoverflow;        }        *++yyssp = yystate = yytable[yyn];        *++yyvsp = yylval;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -