📄 ael.flex
字号:
yymore(); }<argg>{NOARGG}\) { if ( pbcpop(')') ) { /* error */ STORE_LOC; ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ')' in expression!\n", my_file, my_lineno, my_col); BEGIN(0); yylval->str = strdup(yytext); return word; } parencount--; if( parencount >= 0){ yymore(); } else { STORE_LOC; BEGIN(0); if ( !strcmp(yytext, ")") ) return RP; yylval->str = strdup(yytext); yylval->str[yyleng-1] = '\0'; /* trim trailing ')' */ unput(')'); return word; } }<argg>{NOARGG}\, { if( parencount != 0) { /* printf("Folding in a comma!\n"); */ yymore(); } else { STORE_LOC; if( !strcmp(yytext,"," ) ) return COMMA; yylval->str = strdup(yytext); yylval->str[yyleng-1] = '\0'; unput(','); return word; } }<argg>{NOARGG}[\]\}] { char c = yytext[yyleng-1]; if ( pbcpop(c) ) { /* error */ STORE_LOC; ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '%c' in expression!\n", my_file, my_lineno, my_col, c); BEGIN(0); yylval->str = strdup(yytext); return word; } yymore(); } /* * context used to find tokens in the right hand side of assignments, * or in the first and second operand of a 'for'. As above, match * commas and use ';' as a separator (hence return it as a separate token). */<semic>{NOSEMIC}[\(\[\{] { char c = yytext[yyleng-1]; yymore(); pbcpush(c); }<semic>{NOSEMIC}[\)\]\}] { char c = yytext[yyleng-1]; if ( pbcpop(c) ) { /* error */ STORE_LOC; ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '%c' in expression!\n", my_file, my_lineno, my_col, c); BEGIN(0); yylval->str = strdup(yytext); return word; } yymore(); }<semic>{NOSEMIC}; { STORE_LOC; yylval->str = strdup(yytext); yylval->str[yyleng-1] = '\0'; unput(';'); BEGIN(0); return word; }\#include[ \t]+\"[^\"]+\" { FILE *in1; char fnamebuf[1024],*p1,*p2; int error = 1; /* don't use the file if set */ p1 = strchr(yytext,'"'); p2 = strrchr(yytext,'"'); if ( include_stack_index >= MAX_INCLUDE_DEPTH ) { ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Includes nested too deeply! Wow!!! How did you do that?\n", my_file, my_lineno, my_col); } else if ( (int)(p2-p1) > sizeof(fnamebuf) - 1 ) { ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Filename is incredibly way too long (%d chars!). Inclusion ignored!\n", my_file, my_lineno, my_col, yyleng - 10); } else { int i; strncpy(fnamebuf, p1, p2-p1); fnamebuf[p2-p1] = 0; for (i=0; i<include_stack_index; i++) { if ( !strcmp(fnamebuf,include_stack[i].fname )) { ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Nice Try!!! But %s has already been included (perhaps by another file), and would cause an infinite loop of file inclusions!!! Include directive ignored\n", my_file, my_lineno, my_col, fnamebuf); break; } } if (i == include_stack_index) error = 0; /* we can use this file */ } if ( !error ) { /* valid file name */ *p2 = 0; /* relative vs. absolute */ if (*(p1+1) != '/') snprintf(fnamebuf, sizeof(fnamebuf), "%s/%s", ast_config_AST_CONFIG_DIR, p1 + 1); else#if defined(STANDALONE) || defined(LOW_MEMORY) || defined(STANDALONE_AEL) strncpy(fnamebuf, p1 + 1, sizeof(fnamebuf) - 1);#else ast_copy_string(fnamebuf, p1 + 1, sizeof(fnamebuf));#endif in1 = fopen( fnamebuf, "r" ); if ( ! in1 ) { ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Couldn't find the include file: %s; ignoring the Include directive!\n", my_file, my_lineno, my_col, fnamebuf); } else { char *buffer; struct stat stats; stat(fnamebuf, &stats); buffer = (char*)malloc(stats.st_size+1); fread(buffer, 1, stats.st_size, in1); buffer[stats.st_size] = 0; ast_log(LOG_NOTICE," --Read in included file %s, %d chars\n",fnamebuf, (int)stats.st_size); fclose(in1); include_stack[include_stack_index].fname = my_file; my_file = strdup(fnamebuf); include_stack[include_stack_index].lineno = my_lineno; include_stack[include_stack_index].colno = my_col+yyleng; include_stack[include_stack_index++].bufstate = YY_CURRENT_BUFFER; yy_switch_to_buffer(ael_yy_scan_string (buffer ,yyscanner),yyscanner); free(buffer); my_lineno = 1; my_col = 1; BEGIN(INITIAL); } } }<<EOF>> { if ( --include_stack_index < 0 ) { yyterminate(); } else { free(my_file); yy_delete_buffer( YY_CURRENT_BUFFER, yyscanner ); yy_switch_to_buffer(include_stack[include_stack_index].bufstate, yyscanner ); my_lineno = include_stack[include_stack_index].lineno; my_col = include_stack[include_stack_index].colno; my_file = include_stack[include_stack_index].fname; } }%%static void pbcpush(char x){ pbcstack[pbcpos++] = x;}static int pbcpop(char x){ if ( ( x == ')' && pbcstack[pbcpos-1] == '(' ) || ( x == ']' && pbcstack[pbcpos-1] == '[' ) || ( x == '}' && pbcstack[pbcpos-1] == '{' )) { pbcpos--; return 0; } return 1; /* error */}static int c_prevword(void){ char *c = prev_word; if (c == NULL) return 0; while ( *c ) { switch (*c) { case '{': case '[': case '(': pbcpush(*c); break; case '}': case ']': case ')': if (pbcpop(*c)) return 1; break; } c++; } return 0;}/* * The following three functions, reset_*, are used in the bison * code to switch context. As a consequence, we need to * declare them global and add a prototype so that the * compiler does not complain. * * NOTE: yyg is declared because it is used in the BEGIN macros, * though that should be hidden as the macro changes * depending on the flex options that we use - in particular, * %reentrant changes the way the macro is declared; * without %reentrant, BEGIN uses yystart instead of yyg */void reset_parencount(yyscan_t yyscanner );void reset_parencount(yyscan_t yyscanner ){ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; parencount = 0; pbcpos = 0; pbcpush('('); /* push '(' so the last pcbpop (parencount= -1) will succeed */ c_prevword(); BEGIN(paren);}void reset_semicount(yyscan_t yyscanner );void reset_semicount(yyscan_t yyscanner ){ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; pbcpos = 0; BEGIN(semic);}void reset_argcount(yyscan_t yyscanner );void reset_argcount(yyscan_t yyscanner ){ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; parencount = 0; pbcpos = 0; pbcpush('('); /* push '(' so the last pcbpop (parencount= -1) will succeed */ c_prevword(); BEGIN(argg);}/* used elsewhere, but some local vars */struct pval *ael2_parse(char *filename, int *errors){ struct pval *pval; struct parse_io *io; char *buffer; struct stat stats; FILE *fin; /* extern int ael_yydebug; */ io = calloc(sizeof(struct parse_io),1); /* reset the global counters */ prev_word = 0; my_lineno = 1; include_stack_index=0; my_col = 0; /* ael_yydebug = 1; */ ael_yylex_init(&io->scanner); fin = fopen(filename,"r"); if ( !fin ) { ast_log(LOG_ERROR,"File %s could not be opened\n", filename); *errors = 1; return 0; } my_file = strdup(filename); stat(filename, &stats); buffer = (char*)malloc(stats.st_size+2); fread(buffer, 1, stats.st_size, fin); buffer[stats.st_size]=0; fclose(fin); ael_yy_scan_string (buffer ,io->scanner); ael_yyset_lineno(1 , io->scanner); /* ael_yyset_in (fin , io->scanner); OLD WAY */ ael_yyparse(io); pval = io->pval; *errors = io->syntax_error_count; ael_yylex_destroy(io->scanner); free(buffer); free(io); return pval;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -