2006-04-24 17:41:27 +00:00
%{
/*
2006-04-26 18:43:29 +00:00
* Asterisk -- An open source telephony toolkit.
2006-04-24 17:41:27 +00:00
*
* Copyright (C) 2006, Digium, Inc.
*
* Steve Murphy <murf@parsetree.com>
*
* See http://www.asterisk.org for more information about
* the Asterisk project. Please do not directly contact
* any of the maintainers of this project for assistance;
* the project provides a web site, mailing lists and IRC
* channels for your use.
*
* This program is free software, distributed under the terms of
* the GNU General Public License Version 2. See the LICENSE file
* at the top of the source tree.
*/
/*! \file
*
* \brief Bison Grammar description of AEL2.
2006-04-26 18:43:29 +00:00
*
2006-04-24 17:41:27 +00:00
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "asterisk/logger.h"
2006-04-27 17:43:49 +00:00
#include "asterisk/utils.h" /* ast_calloc() */
2006-04-24 17:41:27 +00:00
#include "asterisk/ael_structs.h"
2006-04-27 18:09:20 +00:00
/* create a new object with start-end marker */
2006-04-26 22:41:16 +00:00
static pval *npval(pvaltype type, int first_line, int last_line,
int first_column, int last_column);
2006-04-27 18:09:20 +00:00
2006-04-26 22:41:16 +00:00
static void linku1(pval *head, pval *tail);
void reset_parencount(yyscan_t yyscanner);
void reset_semicount(yyscan_t yyscanner);
void reset_argcount(yyscan_t yyscanner );
2006-04-24 17:41:27 +00:00
#define YYLEX_PARAM ((struct parse_io *)parseio)->scanner
#define YYERROR_VERBOSE 1
extern char *my_file;
#ifdef AAL_ARGCHECK
int ael_is_funcname(char *name);
#endif
2006-04-26 22:41:16 +00:00
static char *ael_token_subst(char *mess);
2006-04-26 18:43:29 +00:00
2006-04-24 17:41:27 +00:00
%}
%union {
char *str;
struct pval *pval;
}
%{
/* declaring these AFTER the union makes things a lot simpler! */
void yyerror(YYLTYPE *locp, struct parse_io *parseio, char const *s);
int ael_yylex (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , void * yyscanner);
2006-04-26 18:43:29 +00:00
2006-04-27 18:09:20 +00:00
/* create a new object with start-end marker, simplified interface.
* Must be declared here because YYLTYPE is not known before
*/
static pval *npval2(pvaltype type, YYLTYPE *first, YYLTYPE *last);
2006-04-24 17:41:27 +00:00
%}
2006-04-26 18:43:29 +00:00
2006-04-24 17:41:27 +00:00
%token KW_CONTEXT LC RC LP RP SEMI EQ COMMA COLON AMPER BAR AT
%token KW_MACRO KW_GLOBALS KW_IGNOREPAT KW_SWITCH KW_IF KW_IFTIME KW_ELSE KW_RANDOM KW_ABSTRACT
%token EXTENMARK KW_GOTO KW_JUMP KW_RETURN KW_BREAK KW_CONTINUE KW_REGEXTEN KW_HINT
%token KW_FOR KW_WHILE KW_CASE KW_PATTERN KW_DEFAULT KW_CATCH KW_SWITCHES KW_ESWITCHES
%token KW_INCLUDES
%token <str> word
%type <pval>includes
%type <pval>includeslist
%type <pval>switchlist
%type <pval>eswitches
%type <pval>switches
%type <pval>macro_statement
%type <pval>macro_statements
%type <pval>case_statement
%type <pval>case_statements
%type <pval>eval_arglist
%type <pval>application_call
%type <pval>application_call_head
%type <pval>macro_call
%type <pval>target jumptarget
%type <pval>statement
%type <pval>switch_head
2006-04-27 19:51:59 +00:00
2006-04-24 17:41:27 +00:00
%type <pval>if_head
%type <pval>random_head
%type <pval>iftime_head
%type <pval>statements
%type <pval>extension
%type <pval>ignorepat
%type <pval>element
%type <pval>elements
%type <pval>arglist
%type <pval>global_statement
%type <pval>global_statements
%type <pval>globals
%type <pval>macro
%type <pval>context
%type <pval>object
2006-04-26 18:43:29 +00:00
%type <pval>objects
%type <pval>file
2006-04-24 17:41:27 +00:00
2006-04-27 19:51:59 +00:00
%type <str>goto_word
%type <str>word_list
%type <str>word3_list
%type <str>includedname
/*
* OPTIONS
*/
%locations /* track source location using @n variables (yylloc in flex) */
%pure-parser /* pass yylval and yylloc as arguments to yylex(). */
2006-04-24 17:41:27 +00:00
%name-prefix="ael_yy"
2006-04-27 19:51:59 +00:00
/*
* add an additional argument, parseio, to yyparse(),
* which is then accessible in the grammar actions
*/
2006-04-24 17:41:27 +00:00
%parse-param {struct parse_io *parseio}
2006-04-27 19:51:59 +00:00
2006-04-26 18:43:29 +00:00
/* there will be two shift/reduce conflicts, they involve the if statement, where a single statement occurs not wrapped in curlies in the "true" section
2006-04-24 17:41:27 +00:00
the default action to shift will attach the else to the preceeding if. */
%expect 5
%error-verbose
2006-04-27 19:51:59 +00:00
/*
* declare destructors for objects.
* The former is for pval, the latter for strings.
2006-04-27 21:09:52 +00:00
* NOTE: we must not have a destructor for a 'file' object.
2006-04-27 19:51:59 +00:00
*/
%destructor {
2006-04-27 21:09:52 +00:00
destroy_pval($$);
prev_word=0;
2006-04-27 19:51:59 +00:00
} includes includeslist switchlist eswitches switches
macro_statement macro_statements case_statement case_statements
eval_arglist application_call application_call_head
macro_call target jumptarget statement switch_head
if_head random_head iftime_head statements extension
ignorepat element elements arglist global_statement
global_statements globals macro context object objects
2006-04-24 17:41:27 +00:00
%destructor { free($$);} word word_list goto_word word3_list includedname
%%
file : objects { $$ = parseio->pval = $1; }
;
objects : object {$$=$1;}
2006-04-27 02:00:35 +00:00
| objects object
{
if ( $1 && $2 ) {
$$=$1;
linku1($$,$2);
} else if ( $1 ) {
$$=$1;
} else if ( $2 ) {
$$=$2;
}
}
2006-04-24 17:41:27 +00:00
| objects error {$$=$1;}
;
object : context {$$=$1;}
| macro {$$=$1;}
| globals {$$=$1;}
| SEMI {$$=0;/* allow older docs to be read */}
;
2006-04-27 02:00:35 +00:00
context : KW_CONTEXT word LC elements RC {
2006-04-27 18:09:20 +00:00
$$ = npval2(PV_CONTEXT, &@1, &@5);
2006-04-27 02:00:35 +00:00
$$->u1.str = $2;
$$->u2.statements = $4; }
| KW_CONTEXT word LC RC /* empty context OK */ {
2006-04-27 18:18:12 +00:00
$$ = npval2(PV_CONTEXT, &@1, &@4);
2006-04-27 02:00:35 +00:00
$$->u1.str = $2; }
| KW_CONTEXT KW_DEFAULT LC elements RC {
2006-04-27 18:18:12 +00:00
$$ = npval2(PV_CONTEXT, &@1, &@5);
2006-04-27 02:00:35 +00:00
$$->u1.str = strdup("default");
$$->u2.statements = $4; }
| KW_CONTEXT KW_DEFAULT LC RC /* empty context OK */ {
2006-04-27 18:18:12 +00:00
$$ = npval2(PV_CONTEXT, &@1, &@4);
2006-04-27 02:00:35 +00:00
$$->u1.str = strdup("default"); }
| KW_ABSTRACT KW_CONTEXT word LC elements RC {
2006-04-27 18:18:12 +00:00
$$ = npval2(PV_CONTEXT, &@1, &@6);
2006-04-27 02:00:35 +00:00
$$->u1.str = $3;
$$->u2.statements = $5;
$$->u3.abstract = 1; }
| KW_ABSTRACT KW_CONTEXT word LC RC /* empty context OK */ {
2006-04-27 18:18:12 +00:00
$$ = npval2(PV_CONTEXT, &@1, &@5);
2006-04-27 02:00:35 +00:00
$$->u1.str = $3;
$$->u3.abstract = 1; }
| KW_ABSTRACT KW_CONTEXT KW_DEFAULT LC elements RC {
2006-04-27 18:18:12 +00:00
$$ = npval2(PV_CONTEXT, &@1, &@6);
2006-04-27 02:00:35 +00:00
$$->u1.str = strdup("default");
$$->u2.statements = $5;
$$->u3.abstract = 1; }
| KW_ABSTRACT KW_CONTEXT KW_DEFAULT LC RC /* empty context OK */ {
2006-04-27 18:18:12 +00:00
$$ = npval2(PV_CONTEXT, &@1, &@5);
2006-04-27 02:00:35 +00:00
$$->u1.str = strdup("default");
$$->u3.abstract = 1; }
2006-04-24 17:41:27 +00:00
;
2006-04-27 02:29:32 +00:00
macro : KW_MACRO word LP arglist RP LC macro_statements RC {
2006-04-27 18:18:12 +00:00
$$ = npval2(PV_MACRO, &@1, &@8);
2006-04-27 02:29:32 +00:00
$$->u1.str = $2; $$->u2.arglist = $4; $$->u3.macro_statements = $7; }
| KW_MACRO word LP arglist RP LC RC {
2006-04-28 10:06:10 +00:00
$$ = npval2(PV_MACRO, &@1, &@7);
2006-04-27 02:29:32 +00:00
$$->u1.str = $2; $$->u2.arglist = $4; }
| KW_MACRO word LP RP LC macro_statements RC {
2006-04-28 10:06:10 +00:00
$$ = npval2(PV_MACRO, &@1, &@7);
$$->u1.str = $2;
$$->u3.macro_statements = $6; }
2006-04-27 02:29:32 +00:00
| KW_MACRO word LP RP LC RC {
2006-04-28 10:06:10 +00:00
$$ = npval2(PV_MACRO, &@1, &@6);
$$->u1.str = $2; }
2006-04-24 17:41:27 +00:00
;
2006-04-27 02:29:32 +00:00
globals : KW_GLOBALS LC global_statements RC {
2006-04-28 10:06:10 +00:00
$$ = npval2(PV_GLOBALS, &@1, &@4);
2006-04-27 02:29:32 +00:00
$$->u1.statements = $3;}
2006-04-28 10:06:10 +00:00
| KW_GLOBALS LC RC { /* empty globals is OK */
$$ = npval2(PV_GLOBALS, &@1, &@3); }
2006-04-24 17:41:27 +00:00
;
global_statements : global_statement {$$=$1;}
| global_statements global_statement {$$=$1; linku1($$,$2);}
| global_statements error {$$=$1;}
;
2006-04-27 02:29:32 +00:00
global_statement : word EQ { reset_semicount(parseio->scanner); } word SEMI {
2006-04-28 10:06:10 +00:00
$$ = npval2(PV_VARDEC, &@1, &@5);
2006-04-27 02:29:32 +00:00
$$->u1.str = $1;
$$->u2.val = $4; }
2006-04-24 17:41:27 +00:00
;
2006-04-27 02:29:32 +00:00
arglist : word {
2006-04-28 11:20:21 +00:00
$$= npval2(PV_WORD, &@1, &@1);
2006-04-27 02:29:32 +00:00
$$->u1.str = $1; }
| arglist COMMA word {
2006-04-28 11:20:21 +00:00
pval *z = npval2(PV_WORD, &@1, &@3);
2006-04-27 02:29:32 +00:00
z->u1.str = $3;
$$=$1;
linku1($$,z); }
2006-04-24 17:41:27 +00:00
| arglist error {$$=$1;}
;
elements : element { $$=$1;}
2006-04-26 18:43:29 +00:00
| error {$$=0;}
| elements element { if ( $1 && $2 ) {$$=$1; linku1($$,$2);}
else if ( $1 ) {$$=$1;}
else if ( $2 ) {$$=$2;} }
2006-04-24 17:41:27 +00:00
| elements error { $$=$1;}
;
element : extension {$$=$1;}
| includes {$$=$1;}
| switches {$$=$1;}
| eswitches {$$=$1;}
| ignorepat {$$=$1;}
2006-04-27 02:29:32 +00:00
| word EQ { reset_semicount(parseio->scanner); } word SEMI {
2006-04-27 18:26:37 +00:00
$$ = npval2(PV_VARDEC, &@1, &@5);
2006-04-27 02:29:32 +00:00
$$->u1.str = $1;
$$->u2.val = $4; }
2006-04-26 18:43:29 +00:00
| word error {free($1); $$=0;}
2006-04-24 17:41:27 +00:00
| SEMI {$$=0;/* allow older docs to be read */}
;
2006-04-27 02:29:32 +00:00
ignorepat : KW_IGNOREPAT EXTENMARK word SEMI {
2006-04-27 18:26:37 +00:00
$$ = npval2(PV_IGNOREPAT, &@1, &@4);
2006-04-27 02:29:32 +00:00
$$->u1.str = $3;}
2006-04-24 17:41:27 +00:00
;
2006-04-27 02:29:32 +00:00
extension : word EXTENMARK statement {
2006-04-28 11:20:21 +00:00
$$ = npval2(PV_EXTENSION, &@1, &@3);
2006-04-27 02:29:32 +00:00
$$->u1.str = $1;
$$->u2.statements = $3; }
| KW_REGEXTEN word EXTENMARK statement {
2006-04-28 11:20:21 +00:00
$$ = npval2(PV_EXTENSION, &@1, &@4);
2006-04-27 02:29:32 +00:00
$$->u1.str = $2;
$$->u2.statements = $4;
$$->u4.regexten=1;}
| KW_HINT LP word3_list RP word EXTENMARK statement {
2006-04-28 11:20:21 +00:00
$$ = npval2(PV_EXTENSION, &@1, &@7);
2006-04-27 02:29:32 +00:00
$$->u1.str = $5;
$$->u2.statements = $7;
$$->u3.hints = $3;}
| KW_REGEXTEN KW_HINT LP word3_list RP word EXTENMARK statement {
2006-04-28 11:20:21 +00:00
$$ = npval2(PV_EXTENSION, &@1, &@8);
2006-04-27 02:29:32 +00:00
$$->u1.str = $6;
$$->u2.statements = $8;
$$->u4.regexten=1;
$$->u3.hints = $4;}
2006-04-24 17:41:27 +00:00
;
statements : statement {$$=$1;}
2006-04-26 18:43:29 +00:00
| statements statement {if ( $1 && $2 ) {$$=$1; linku1($$,$2);}
2006-04-24 17:41:27 +00:00
else if ( $1 ) {$$=$1;}
else if ( $2 ) {$$=$2;} }
| statements error {$$=$1;}
;
2006-04-27 02:29:32 +00:00
if_head : KW_IF LP { reset_parencount(parseio->scanner); } word_list RP {
2006-04-28 11:20:21 +00:00
$$= npval2(PV_IF, &@1, &@5);
2006-04-27 02:29:32 +00:00
$$->u1.str = $4; }
;
random_head : KW_RANDOM LP { reset_parencount(parseio->scanner); } word_list RP {
2006-04-28 11:20:21 +00:00
$$ = npval2(PV_RANDOM, &@1, &@5);
2006-04-27 02:29:32 +00:00
$$->u1.str=$4;}
;
iftime_head : KW_IFTIME LP word3_list COLON word3_list COLON word3_list
BAR word3_list BAR word3_list BAR word3_list RP {
2006-04-27 18:26:37 +00:00
$$ = npval2(PV_IFTIME, &@1, &@5); /* XXX really @5 or more ? */
$$->u1.list = npval2(PV_WORD, &@3, &@3);
2006-04-27 08:31:18 +00:00
asprintf(&($$->u1.list->u1.str), "%s:%s:%s", $3, $5, $7);
2006-04-27 02:29:32 +00:00
free($3);
free($5);
free($7);
2006-04-27 18:26:37 +00:00
$$->u1.list->next = npval2(PV_WORD, &@9, &@9);
2006-04-27 02:29:32 +00:00
$$->u1.list->next->u1.str = $9;
2006-04-27 18:26:37 +00:00
$$->u1.list->next->next = npval2(PV_WORD, &@11, &@11);
2006-04-27 02:29:32 +00:00
$$->u1.list->next->next->u1.str = $11;
2006-04-27 18:26:37 +00:00
$$->u1.list->next->next->next = npval2(PV_WORD, &@13, &@13);
2006-04-27 02:29:32 +00:00
$$->u1.list->next->next->next->u1.str = $13;
prev_word = 0;
}
| KW_IFTIME LP word BAR word3_list BAR word3_list BAR word3_list RP {
2006-04-27 18:26:37 +00:00
$$ = npval2(PV_IFTIME, &@1, &@5); /* XXX @5 or greater ? */
$$->u1.list = npval2(PV_WORD, &@3, &@3);
2006-04-27 02:29:32 +00:00
$$->u1.list->u1.str = $3;
2006-04-27 18:26:37 +00:00
$$->u1.list->next = npval2(PV_WORD, &@5, &@5);
2006-04-27 02:29:32 +00:00
$$->u1.list->next->u1.str = $5;
2006-04-27 18:26:37 +00:00
$$->u1.list->next->next = npval2(PV_WORD, &@7, &@7);
2006-04-27 02:29:32 +00:00
$$->u1.list->next->next->u1.str = $7;
2006-04-27 18:26:37 +00:00
$$->u1.list->next->next->next = npval2(PV_WORD, &@9, &@9);
2006-04-27 02:29:32 +00:00
$$->u1.list->next->next->next->u1.str = $9;
prev_word = 0;
}
2006-04-24 17:41:27 +00:00
;
/* word_list is a hack to fix a problem with context switching between bison and flex;
2006-04-26 18:43:29 +00:00
by the time you register a new context with flex, you've already got a look-ahead token
2006-04-24 17:41:27 +00:00
from the old context, with no way to put it back and start afresh. So, we kludge this
and merge the words back together. */
2006-04-26 18:43:29 +00:00
word_list : word { $$ = $1;}
2006-04-27 08:24:00 +00:00
| word word {
2006-04-27 08:31:18 +00:00
asprintf(&($$), "%s%s", $1, $2);
2006-04-27 08:24:00 +00:00
free($1);
free($2);
prev_word = $$;}
2006-04-24 17:41:27 +00:00
;
2006-04-27 18:26:37 +00:00
2006-04-26 18:43:29 +00:00
word3_list : word { $$ = $1;}
2006-04-27 08:24:00 +00:00
| word word {
2006-04-27 08:31:18 +00:00
asprintf(&($$), "%s%s", $1, $2);
2006-04-27 08:24:00 +00:00
free($1);
free($2);
prev_word = $$;}
| word word word {
2006-04-27 08:31:18 +00:00
asprintf(&($$), "%s%s%s", $1, $2, $3);
2006-04-27 08:24:00 +00:00
free($1);
free($2);
free($3);
prev_word=$$;}
2006-04-24 17:41:27 +00:00
;
goto_word : word { $$ = $1;}
2006-04-27 08:24:00 +00:00
| word word {
2006-04-27 08:31:18 +00:00
asprintf(&($$), "%s%s", $1, $2);
2006-04-27 08:24:00 +00:00
free($1);
free($2);}
| word COLON word {
2006-04-27 08:31:18 +00:00
asprintf(&($$), "%s:%s", $1, $3);
2006-04-27 08:24:00 +00:00
free($1);
free($3);}
2006-04-24 17:41:27 +00:00
;
2006-04-27 16:40:25 +00:00
switch_head : KW_SWITCH LP { reset_parencount(parseio->scanner); } word RP LC {
2006-04-28 11:20:21 +00:00
$$ = npval2(PV_SWITCH, &@1, &@6);
2006-04-27 16:40:25 +00:00
$$->u1.str = $4; }
2006-04-24 17:41:27 +00:00
;
2006-04-27 18:09:20 +00:00
/*
* Definition of a statememt in our language
*/
2006-04-27 16:40:25 +00:00
statement : LC statements RC {
2006-04-27 18:09:20 +00:00
$$ = npval2(PV_STATEMENTBLOCK, &@1, &@3);
2006-04-27 16:40:25 +00:00
$$->u1.list = $2; }
| word EQ {reset_semicount(parseio->scanner);} word SEMI {
2006-04-27 19:14:07 +00:00
$$ = npval2(PV_VARDEC, &@1, &@5);
2006-04-27 16:40:25 +00:00
$$->u1.str = $1;
$$->u2.val = $4; }
| KW_GOTO target SEMI {
2006-04-27 19:14:07 +00:00
$$ = npval2(PV_GOTO, &@1, &@3);
2006-04-27 16:40:25 +00:00
$$->u1.list = $2;}
| KW_JUMP jumptarget SEMI {
2006-04-28 06:26:27 +00:00
$$ = npval2(PV_GOTO, &@1, &@3);
2006-04-27 16:40:25 +00:00
$$->u1.list = $2;}
| word COLON {
2006-04-28 06:26:27 +00:00
$$ = npval2(PV_LABEL, &@1, &@2);
2006-04-27 16:40:25 +00:00
$$->u1.str = $1; }
2006-04-24 17:41:27 +00:00
| KW_FOR LP {reset_semicount(parseio->scanner);} word SEMI
{reset_semicount(parseio->scanner);} word SEMI
2006-04-27 16:40:25 +00:00
{reset_parencount(parseio->scanner);} word RP statement {
2006-04-28 06:26:27 +00:00
$$ = npval2(PV_FOR, &@1, &@12);
2006-04-27 16:40:25 +00:00
$$->u1.for_init = $4;
$$->u2.for_test=$7;
$$->u3.for_inc = $10;
$$->u4.for_statements = $12;}
| KW_WHILE LP {reset_parencount(parseio->scanner);} word RP statement {
2006-04-28 06:26:27 +00:00
$$ = npval2(PV_WHILE, &@1, &@6);
2006-04-27 16:40:25 +00:00
$$->u1.str = $4;
$$->u2.statements = $6; }
| switch_head RC /* empty list OK */ {
$$=$1;
$$->endline = @2.last_line;
$$->endcol = @2.last_column;}
| switch_head case_statements RC {
$$=$1;
$$->u2.statements = $2;
$$->endline = @3.last_line;
$$->endcol = @3.last_column;}
| AMPER macro_call SEMI {
$$ = $2;
$$->endline = @2.last_line;
$$->endcol = @2.last_column;}
| application_call SEMI {
$$ = $1;
$$->endline = @2.last_line;
$$->endcol = @2.last_column;}
2006-04-27 08:37:40 +00:00
| word SEMI {
2006-04-28 11:20:21 +00:00
$$= npval2(PV_APPLICATION_CALL, &@1, &@2);
2006-04-27 08:37:40 +00:00
$$->u1.str = $1;}
2006-04-24 17:41:27 +00:00
| application_call EQ {reset_semicount(parseio->scanner);} word SEMI {
2006-04-27 08:37:40 +00:00
char *bufx;
int tot=0;
pval *pptr;
2006-04-28 11:20:21 +00:00
$$ = npval2(PV_VARDEC, &@1, &@5);
2006-04-27 08:37:40 +00:00
$$->u2.val=$4;
/* rebuild the original string-- this is not an app call, it's an unwrapped vardec, with a func call on the LHS */
/* string to big to fit in the buffer? */
tot+=strlen($1->u1.str);
for(pptr=$1->u2.arglist;pptr;pptr=pptr->next) {
tot+=strlen(pptr->u1.str);
tot++; /* for a sep like a comma */
}
tot+=4; /* for safety */
2006-04-27 17:43:49 +00:00
bufx = ast_calloc(1, tot);
2006-04-27 08:37:40 +00:00
strcpy(bufx,$1->u1.str);
strcat(bufx,"(");
/* XXX need to advance the pointer or the loop is very inefficient */
for (pptr=$1->u2.arglist;pptr;pptr=pptr->next) {
if ( pptr != $1->u2.arglist )
strcat(bufx,",");
strcat(bufx,pptr->u1.str);
}
strcat(bufx,")");
2006-04-24 17:41:27 +00:00
#ifdef AAL_ARGCHECK
2006-04-27 08:37:40 +00:00
if ( !ael_is_funcname($1->u1.str) )
ast_log(LOG_WARNING, "==== File: %s, Line %d, Cols: %d-%d: Function call? The name %s is not in my internal list of function names\n",
my_file, @1.first_line, @1.first_column, @1.last_column, $1->u1.str);
2006-04-24 17:41:27 +00:00
#endif
2006-04-27 08:37:40 +00:00
$$->u1.str = bufx;
destroy_pval($1); /* the app call it is not, get rid of that chain */
prev_word = 0;
}
2006-04-28 11:20:21 +00:00
| KW_BREAK SEMI { $$ = npval2(PV_BREAK, &@1, &@2); }
| KW_RETURN SEMI { $$ = npval2(PV_RETURN, &@1, &@2); }
| KW_CONTINUE SEMI { $$ = npval2(PV_CONTINUE, &@1, &@2); }
2006-04-27 16:40:25 +00:00
| random_head statement {
$$=$1;
$$->u2.statements = $2;
$$->endline = @2.last_line;
$$->endcol = @2.last_column;}
| random_head statement KW_ELSE statement {
$$=$1;
$$->u2.statements = $2;
$$->endline = @2.last_line;
$$->endcol = @2.last_column;
$$->u3.else_statements = $4;}
| if_head statement {
$$=$1;
$$->u2.statements = $2;
$$->endline = @2.last_line;
$$->endcol = @2.last_column;}
| if_head statement KW_ELSE statement {
$$=$1;
$$->u2.statements = $2;
$$->endline = @2.last_line;
$$->endcol = @2.last_column;
$$->u3.else_statements = $4;}
| iftime_head statement {
$$=$1;
$$->u2.statements = $2;
$$->endline = @2.last_line;
$$->endcol = @2.last_column;}
| iftime_head statement KW_ELSE statement {
$$=$1;
$$->u2.statements = $2;
$$->endline = @2.last_line;
$$->endcol = @2.last_column;
$$->u3.else_statements = $4;}
2006-04-24 17:41:27 +00:00
| SEMI { $$=0; }
;
2006-04-28 11:20:21 +00:00
target : goto_word { $$ = npval2(PV_WORD, &@1, &@1);
$$->u1.str = $1;}
2006-04-27 06:44:38 +00:00
| goto_word BAR goto_word {
2006-04-28 11:20:21 +00:00
$$ = npval2(PV_WORD, &@1, &@1);
2006-04-27 06:44:38 +00:00
$$->u1.str = $1;
2006-04-28 11:20:21 +00:00
$$->next = npval2(PV_WORD, &@3, &@3);
2006-04-27 06:44:38 +00:00
$$->next->u1.str = $3;}
| goto_word COMMA goto_word {
2006-04-28 11:20:21 +00:00
$$ = npval2(PV_WORD, &@1, &@1);
2006-04-27 06:44:38 +00:00
$$->u1.str = $1;
2006-04-28 11:20:21 +00:00
$$->next = npval2(PV_WORD, &@3, &@3);
2006-04-27 06:44:38 +00:00
$$->next->u1.str = $3;}
2006-04-27 17:59:09 +00:00
| goto_word BAR goto_word BAR goto_word {
2006-04-28 11:20:21 +00:00
$$ = npval2(PV_WORD, &@1, &@1);
2006-04-27 17:59:09 +00:00
$$->u1.str = $1;
2006-04-28 11:20:21 +00:00
$$->next = npval2(PV_WORD, &@3, &@3);
2006-04-27 08:37:40 +00:00
$$->next->u1.str = $3;
2006-04-28 11:20:21 +00:00
$$->next->next = npval2(PV_WORD, &@5, &@5);
2006-04-27 08:37:40 +00:00
$$->next->next->u1.str = $5; }
2006-04-27 17:59:09 +00:00
| goto_word COMMA goto_word COMMA goto_word {
2006-04-28 11:20:21 +00:00
$$ = npval2(PV_WORD, &@1, &@1);
2006-04-27 17:59:09 +00:00
$$->u1.str = $1;
2006-04-28 11:20:21 +00:00
$$->next = npval2(PV_WORD, &@3, &@3);
2006-04-27 08:37:40 +00:00
$$->next->u1.str = $3;
2006-04-28 11:20:21 +00:00
$$->next->next = npval2(PV_WORD, &@5, &@5);
2006-04-27 08:37:40 +00:00
$$->next->next->u1.str = $5; }
2006-04-27 17:59:09 +00:00
| KW_DEFAULT BAR goto_word BAR goto_word {
2006-04-28 11:20:21 +00:00
$$ = npval2(PV_WORD, &@1, &@1);
2006-04-27 17:59:09 +00:00
$$->u1.str = strdup("default");
2006-04-28 11:20:21 +00:00
$$->next = npval2(PV_WORD, &@3, &@3);
2006-04-27 08:37:40 +00:00
$$->next->u1.str = $3;
2006-04-28 11:20:21 +00:00
$$->next->next = npval2(PV_WORD, &@5, &@5);
2006-04-27 08:37:40 +00:00
$$->next->next->u1.str = $5; }
2006-04-27 17:59:09 +00:00
| KW_DEFAULT COMMA goto_word COMMA goto_word {
2006-04-28 11:20:21 +00:00
$$ = npval2(PV_WORD, &@1, &@1);
2006-04-27 17:59:09 +00:00
$$->u1.str = strdup("default");
2006-04-28 11:20:21 +00:00
$$->next = npval2(PV_WORD, &@3, &@3);
2006-04-27 08:37:40 +00:00
$$->next->u1.str = $3;
2006-04-28 11:20:21 +00:00
$$->next->next = npval2(PV_WORD, &@5, &@5);
2006-04-27 08:37:40 +00:00
$$->next->next->u1.str = $5; }
2006-04-24 17:41:27 +00:00
;
2006-04-27 17:59:09 +00:00
jumptarget : goto_word {
2006-04-28 11:20:21 +00:00
$$ = npval2(PV_WORD, &@1, &@1);
2006-04-27 17:59:09 +00:00
$$->u1.str = $1;
2006-04-28 11:20:21 +00:00
$$->next = npval2(PV_WORD, &@1, &@1); /* XXX not really @1 */
2006-04-27 08:37:40 +00:00
$$->next->u1.str = strdup("1");} /* jump extension[,priority][@context] */
2006-04-27 17:59:09 +00:00
| goto_word COMMA goto_word {
2006-04-28 11:20:21 +00:00
$$ = npval2(PV_WORD, &@1, &@1);
2006-04-27 17:59:09 +00:00
$$->u1.str = $1;
2006-04-28 11:20:21 +00:00
$$->next = npval2(PV_WORD, &@3, &@3);
2006-04-27 08:37:40 +00:00
$$->next->u1.str = $3;}
2006-04-27 17:59:09 +00:00
| goto_word COMMA word AT word {
2006-04-28 11:20:21 +00:00
$$ = npval2(PV_WORD, &@1, &@1);
2006-04-27 17:59:09 +00:00
$$->u1.str = $5;
2006-04-28 11:20:21 +00:00
$$->next = npval2(PV_WORD, &@3, &@3);
2006-04-27 08:37:40 +00:00
$$->next->u1.str = $1;
2006-04-28 11:20:21 +00:00
$$->next->next = npval2(PV_WORD, &@5, &@5);
2006-04-27 08:37:40 +00:00
$$->next->next->u1.str = $3; }
2006-04-27 17:59:09 +00:00
| goto_word AT goto_word {
2006-04-28 11:20:21 +00:00
$$ = npval2(PV_WORD, &@1, &@1);
2006-04-27 17:59:09 +00:00
$$->u1.str = $3;
2006-04-28 11:20:21 +00:00
$$->next = npval2(PV_WORD, &@3, &@3);
2006-04-27 08:37:40 +00:00
$$->next->u1.str = $1;
2006-04-28 11:20:21 +00:00
$$->next->next = npval2(PV_WORD, &@3, &@3);
2006-04-27 08:37:40 +00:00
$$->next->next->u1.str = strdup("1"); }
2006-04-27 17:59:09 +00:00
| goto_word COMMA word AT KW_DEFAULT {
2006-04-28 11:20:21 +00:00
$$ = npval2(PV_WORD, &@1, &@1);
2006-04-27 17:59:09 +00:00
$$->u1.str = strdup("default");
2006-04-28 11:20:21 +00:00
$$->next = npval2(PV_WORD, &@3, &@3);
2006-04-27 08:37:40 +00:00
$$->next->u1.str = $1;
2006-04-28 11:20:21 +00:00
$$->next->next = npval2(PV_WORD, &@5, &@5);
2006-04-27 08:37:40 +00:00
$$->next->next->u1.str = $3; }
2006-04-27 17:59:09 +00:00
| goto_word AT KW_DEFAULT {
2006-04-28 11:20:21 +00:00
$$ = npval2(PV_WORD, &@1, &@1);
2006-04-27 17:59:09 +00:00
$$->u1.str = strdup("default");
2006-04-28 11:20:21 +00:00
$$->next = npval2(PV_WORD, &@3, &@3);
2006-04-27 08:37:40 +00:00
$$->next->u1.str = $1;
2006-04-28 11:20:21 +00:00
$$->next->next = npval2(PV_WORD, &@3, &@3);
2006-04-27 08:37:40 +00:00
$$->next->next->u1.str = strdup("1"); }
2006-04-27 06:44:38 +00:00
;
2006-04-24 17:41:27 +00:00
2006-04-27 17:59:09 +00:00
macro_call : word LP {reset_argcount(parseio->scanner);} eval_arglist RP {
2006-04-27 18:18:12 +00:00
/* XXX original code had @2 but i think we need @5 */
$$ = npval2(PV_MACRO_CALL, &@1, &@5);
2006-04-27 17:59:09 +00:00
$$->u1.str = $1;
$$->u2.arglist = $4;}
| word LP RP {
2006-04-27 18:18:12 +00:00
$$= npval2(PV_MACRO_CALL, &@1, &@3);
2006-04-27 17:59:09 +00:00
$$->u1.str = $1; }
2006-04-24 17:41:27 +00:00
;
2006-04-27 08:37:40 +00:00
application_call_head: word {reset_argcount(parseio->scanner);} LP {
if (strcasecmp($1,"goto") == 0) {
2006-04-28 11:20:21 +00:00
$$= npval2(PV_GOTO, &@1, &@3);
2006-04-27 06:44:38 +00:00
free($1); /* won't be using this */
ast_log(LOG_WARNING, "==== File: %s, Line %d, Cols: %d-%d: Suggestion: Use the goto statement instead of the Goto() application call in AEL.\n", my_file, @1.first_line, @1.first_column, @1.last_column );
} else
2006-04-28 11:20:21 +00:00
$$= npval2(PV_APPLICATION_CALL, &@1, &@3);
2006-04-27 06:44:38 +00:00
$$->u1.str = $1; }
2006-04-24 17:41:27 +00:00
;
application_call : application_call_head eval_arglist RP {$$ = $1;
if( $$->type == PV_GOTO )
$$->u1.list = $2;
else
$$->u2.arglist = $2;
$$->endline = @3.last_line; $$->endcol = @3.last_column;}
| application_call_head RP {$$=$1;$$->endline = @2.last_line; $$->endcol = @2.last_column;}
;
2006-04-27 17:59:09 +00:00
eval_arglist : word_list {
2006-04-28 11:20:21 +00:00
$$= npval2(PV_WORD, &@1, &@1);
2006-04-27 17:59:09 +00:00
$$->u1.str = $1;}
| /*nothing! */ {
$$= npval(PV_WORD,0/*@1.first_line*/,0/*@1.last_line*/,0/* @1.first_column*/, 0/*@1.last_column*/);
$$->u1.str = strdup(""); }
| eval_arglist COMMA word {
2006-04-28 11:20:21 +00:00
pval *z = npval2(PV_WORD, &@3, &@3);
2006-04-27 17:59:09 +00:00
$$ = $1;
linku1($1,z);
z->u1.str = $3;}
| eval_arglist COMMA {
2006-04-28 11:20:21 +00:00
pval *z = npval2(PV_WORD, &@2, &@2);
2006-04-27 17:59:09 +00:00
$$ = $1;
linku1($1,z);
z->u1.str = strdup("");}
2006-04-24 17:41:27 +00:00
;
case_statements: case_statement {$$=$1;}
2006-04-26 18:43:29 +00:00
| case_statements case_statement { if ( $1 && $2 ) {$$=$1; linku1($$,$2);}
2006-04-24 17:41:27 +00:00
else if ( $1 ) {$$=$1;}
else if ( $2 ) {$$=$2;} }
;
2006-04-27 17:59:09 +00:00
case_statement: KW_CASE word COLON statements {
2006-04-27 19:14:07 +00:00
$$ = npval2(PV_CASE, &@1, &@3); /* XXX 3 or 4 ? */
$$->u1.str = $2;
$$->u2.statements = $4;}
| KW_DEFAULT COLON statements {
$$ = npval2(PV_DEFAULT, &@1, &@3);
$$->u1.str = NULL;
$$->u2.statements = $3;}
| KW_PATTERN word COLON statements {
$$ = npval2(PV_PATTERN, &@1, &@4); /* XXX@3 or @4 ? */
$$->u1.str = $2;
$$->u2.statements = $4;}
| KW_CASE word COLON {
$$ = npval2(PV_CASE, &@1, &@3);
$$->u1.str = $2;}
| KW_DEFAULT COLON {
$$ = npval2(PV_DEFAULT, &@1, &@2);
$$->u1.str = NULL;}
| KW_PATTERN word COLON {
$$ = npval2(PV_PATTERN, &@1, &@3);
$$->u1.str = $2;}
2006-04-24 17:41:27 +00:00
;
macro_statements: macro_statement {$$ = $1;}
2006-04-26 18:43:29 +00:00
| macro_statements macro_statement { if ( $1 && $2 ) {$$=$1; linku1($$,$2);}
2006-04-24 17:41:27 +00:00
else if ( $1 ) {$$=$1;}
else if ( $2 ) {$$=$2;} }
;
macro_statement : statement {$$=$1;}
2006-04-28 06:26:27 +00:00
| KW_CATCH word LC statements RC {
$$ = npval2(PV_CATCH, &@1, &@5);
$$->u1.str = $2;
$$->u2.statements = $4;}
2006-04-24 17:41:27 +00:00
;
2006-04-28 06:26:27 +00:00
switches : KW_SWITCHES LC switchlist RC {
$$ = npval2(PV_SWITCHES, &@1, &@4);
$$->u1.list = $3; }
| KW_SWITCHES LC RC /* empty switch list OK */ {
$$ = npval2(PV_SWITCHES, &@1, &@3); }
2006-04-24 17:41:27 +00:00
;
2006-04-28 11:20:21 +00:00
eswitches : KW_ESWITCHES LC switchlist RC {
$$ = npval2(PV_ESWITCHES, &@1, &@4);
$$->u1.list = $3; }
| KW_ESWITCHES LC RC { /* empty switch list OK */
$$ = npval2(PV_ESWITCHES, &@1, &@3); } /* if there's nothing to declare, why include it? */
2006-04-24 17:41:27 +00:00
;
2006-04-28 06:26:27 +00:00
switchlist : word SEMI {
$$ = npval2(PV_WORD, &@1, &@2);
$$->u1.str = $1;}
| switchlist word SEMI {
pval *z = npval2(PV_WORD, &@2, &@3);
z->u1.str = $2;
$$=$1;
linku1($$,z); }
2006-04-24 17:41:27 +00:00
| switchlist error {$$=$1;}
;
2006-04-28 11:20:21 +00:00
includeslist : includedname SEMI {
$$ = npval2(PV_WORD, &@1, &@2);
$$->u1.str = $1;}
| includedname BAR word3_list COLON word3_list COLON word3_list
BAR word3_list BAR word3_list BAR word3_list SEMI {
$$ = npval2(PV_WORD, &@1, &@2);
2006-04-27 08:37:40 +00:00
$$->u1.str = $1;
2006-04-28 11:20:21 +00:00
$$->u2.arglist = npval2(PV_WORD, &@3, &@7);
2006-04-27 08:37:40 +00:00
asprintf( &($$->u2.arglist->u1.str), "%s:%s:%s", $3, $5, $7);
free($3);
free($5);
free($7);
2006-04-28 11:20:21 +00:00
$$->u2.arglist->next = npval2(PV_WORD, &@9, &@9);
2006-04-27 08:37:40 +00:00
$$->u2.arglist->next->u1.str = $9;
2006-04-28 11:20:21 +00:00
$$->u2.arglist->next->next = npval2(PV_WORD, &@11, &@11);
2006-04-27 08:37:40 +00:00
$$->u2.arglist->next->next->u1.str = $11;
2006-04-28 11:20:21 +00:00
$$->u2.arglist->next->next->next = npval2(PV_WORD, &@13, &@13);
2006-04-27 08:37:40 +00:00
$$->u2.arglist->next->next->next->u1.str = $13;
prev_word=0;
}
2006-04-24 17:41:27 +00:00
| includedname BAR word BAR word3_list BAR word3_list BAR word3_list SEMI {
2006-04-28 11:20:21 +00:00
$$ = npval2(PV_WORD, &@1, &@2);
2006-04-27 08:37:40 +00:00
$$->u1.str = $1;
2006-04-28 11:20:21 +00:00
$$->u2.arglist = npval2(PV_WORD, &@3, &@3);
2006-04-27 08:37:40 +00:00
$$->u2.arglist->u1.str = $3;
2006-04-28 11:20:21 +00:00
$$->u2.arglist->next = npval2(PV_WORD, &@5, &@5);
2006-04-27 08:37:40 +00:00
$$->u2.arglist->next->u1.str = $5;
2006-04-28 11:20:21 +00:00
$$->u2.arglist->next->next = npval2(PV_WORD, &@7, &@7);
2006-04-27 08:37:40 +00:00
$$->u2.arglist->next->next->u1.str = $7;
2006-04-28 11:20:21 +00:00
$$->u2.arglist->next->next->next = npval2(PV_WORD, &@9, &@9);
2006-04-27 08:37:40 +00:00
$$->u2.arglist->next->next->next->u1.str = $9;
prev_word=0;
}
2006-04-28 06:26:27 +00:00
| includeslist includedname SEMI {
pval *z = npval2(PV_WORD, &@2, &@3); /* XXX don't we need @1-@4 ?*/
$$=$1;
z->u1.str = $2;
linku1($$,z); }
2006-04-28 11:20:21 +00:00
| includeslist includedname BAR word3_list COLON word3_list COLON word3_list
BAR word3_list BAR word3_list BAR word3_list SEMI {
pval *z = npval2(PV_WORD, &@2, &@3);
$$=$1; z->u1.str = $2;
linku1($$,z);
z->u2.arglist = npval2(PV_WORD, &@4, &@4);
2006-04-27 08:37:40 +00:00
asprintf( &($$->u2.arglist->u1.str), "%s:%s:%s", $4, $6, $8);
free($4);
free($6);
free($8);
2006-04-28 11:20:21 +00:00
z->u2.arglist->next = npval2(PV_WORD, &@10, &@10);
2006-04-27 08:37:40 +00:00
z->u2.arglist->next->u1.str = $10;
2006-04-28 11:20:21 +00:00
z->u2.arglist->next->next = npval2(PV_WORD, &@12, &@12);
2006-04-27 08:37:40 +00:00
z->u2.arglist->next->next->u1.str = $12;
2006-04-28 11:20:21 +00:00
z->u2.arglist->next->next->next = npval2(PV_WORD, &@14, &@14);
2006-04-27 08:37:40 +00:00
z->u2.arglist->next->next->next->u1.str = $14;
prev_word=0;
}
2006-04-28 11:20:21 +00:00
| includeslist includedname BAR word BAR word3_list BAR word3_list BAR word3_list SEMI {
pval *z = npval2(PV_WORD, &@2, &@3);
$$=$1;
z->u1.str = $2; linku1($$,z);
z->u2.arglist = npval2(PV_WORD, &@4, &@4);
2006-04-27 08:37:40 +00:00
$$->u2.arglist->u1.str = $4;
2006-04-28 11:20:21 +00:00
z->u2.arglist->next = npval2(PV_WORD, &@6, &@6);
2006-04-27 08:37:40 +00:00
z->u2.arglist->next->u1.str = $6;
2006-04-28 11:20:21 +00:00
z->u2.arglist->next->next = npval2(PV_WORD, &@8, &@8);
2006-04-27 08:37:40 +00:00
z->u2.arglist->next->next->u1.str = $8;
2006-04-28 11:20:21 +00:00
z->u2.arglist->next->next->next = npval2(PV_WORD, &@10, &@10);
2006-04-27 08:37:40 +00:00
z->u2.arglist->next->next->next->u1.str = $10;
prev_word=0;
}
2006-04-24 17:41:27 +00:00
| includeslist error {$$=$1;}
;
includedname : word { $$ = $1;}
2006-04-27 06:44:38 +00:00
| KW_DEFAULT {$$=strdup("default");}
;
2006-04-24 17:41:27 +00:00
2006-04-27 06:44:38 +00:00
includes : KW_INCLUDES LC includeslist RC {
2006-04-27 18:18:12 +00:00
$$ = npval2(PV_INCLUDES, &@1, &@4);
2006-04-27 06:44:38 +00:00
$$->u1.list = $3;}
| KW_INCLUDES LC RC {
2006-04-27 18:18:12 +00:00
$$ = npval2(PV_INCLUDES, &@1, &@3);}
2006-04-24 17:41:27 +00:00
;
%%
2006-04-26 18:43:29 +00:00
static char *token_equivs1[] =
2006-04-24 17:41:27 +00:00
{
"AMPER",
"AT",
"BAR",
"COLON",
"COMMA",
"EQ",
"EXTENMARK",
2006-04-26 18:43:29 +00:00
"KW_BREAK",
"KW_CASE",
"KW_CATCH",
2006-04-24 17:41:27 +00:00
"KW_CONTEXT",
2006-04-26 18:43:29 +00:00
"KW_CONTINUE",
"KW_DEFAULT",
2006-04-24 17:41:27 +00:00
"KW_ELSE",
"KW_ESWITCHES",
2006-04-26 18:43:29 +00:00
"KW_FOR",
2006-04-24 17:41:27 +00:00
"KW_GLOBALS",
"KW_GOTO",
"KW_HINT",
"KW_IFTIME",
"KW_IF",
"KW_IGNOREPAT",
"KW_INCLUDES"
"KW_JUMP",
"KW_MACRO",
2006-04-26 18:43:29 +00:00
"KW_PATTERN",
"KW_REGEXTEN",
"KW_RETURN",
"KW_SWITCHES",
2006-04-24 17:41:27 +00:00
"KW_SWITCH",
2006-04-26 18:43:29 +00:00
"KW_WHILE",
2006-04-24 17:41:27 +00:00
"LC",
"LP",
"RC",
"RP",
"SEMI",
};
2006-04-26 18:43:29 +00:00
static char *token_equivs2[] =
2006-04-24 17:41:27 +00:00
{
"&",
"@",
"|",
":",
",",
"=",
"=>",
2006-04-26 18:43:29 +00:00
"break",
"case",
"catch",
2006-04-24 17:41:27 +00:00
"context",
2006-04-26 18:43:29 +00:00
"continue",
"default",
2006-04-24 17:41:27 +00:00
"else",
"eswitches",
2006-04-26 18:43:29 +00:00
"for",
2006-04-24 17:41:27 +00:00
"globals",
"goto",
"hint",
"ifTime",
"if",
"ignorepat",
"includes"
"jump",
"macro",
2006-04-26 18:43:29 +00:00
"pattern",
"regexten",
"return",
"switches",
2006-04-24 17:41:27 +00:00
"switch",
2006-04-26 18:43:29 +00:00
"while",
2006-04-24 17:41:27 +00:00
"{",
"(",
"}",
")",
";",
};
static char *ael_token_subst(char *mess)
{
/* calc a length, malloc, fill, and return; yyerror had better free it! */
int len=0,i;
char *p;
char *res, *s,*t;
int token_equivs_entries = sizeof(token_equivs1)/sizeof(char*);
for (p=mess; *p; p++) {
for (i=0; i<token_equivs_entries; i++) {
if ( strncmp(p,token_equivs1[i],strlen(token_equivs1[i])) == 0 )
{
len+=strlen(token_equivs2[i])+2;
p += strlen(token_equivs1[i])-1;
break;
}
}
len++;
}
2006-04-27 17:43:49 +00:00
res = ast_calloc(1, len+1);
2006-04-24 17:41:27 +00:00
res[0] = 0;
s = res;
for (p=mess; *p;) {
int found = 0;
for (i=0; i<token_equivs_entries; i++) {
if ( strncmp(p,token_equivs1[i],strlen(token_equivs1[i])) == 0 ) {
*s++ = '\'';
for (t=token_equivs2[i]; *t;) {
*s++ = *t++;
}
*s++ = '\'';
p += strlen(token_equivs1[i]);
found = 1;
break;
}
}
if( !found )
*s++ = *p++;
}
*s++ = 0;
return res;
}
void yyerror(YYLTYPE *locp, struct parse_io *parseio, char const *s)
{
char *s2 = ael_token_subst((char *)s);
if (locp->first_line == locp->last_line) {
ast_log(LOG_ERROR, "==== File: %s, Line %d, Cols: %d-%d: Error: %s\n", my_file, locp->first_line, locp->first_column, locp->last_column, s2);
} else {
ast_log(LOG_ERROR, "==== File: %s, Line %d Col %d to Line %d Col %d: Error: %s\n", my_file, locp->first_line, locp->first_column, locp->last_line, locp->last_column, s2);
}
free(s2);
parseio->syntax_error_count++;
}
2006-04-27 17:39:55 +00:00
static struct pval *npval(pvaltype type, int first_line, int last_line,
int first_column, int last_column)
2006-04-24 17:41:27 +00:00
{
extern char *my_file;
2006-04-27 17:43:49 +00:00
pval *z = ast_calloc(1, sizeof(struct pval));
2006-04-24 17:41:27 +00:00
z->type = type;
z->startline = first_line;
z->endline = last_line;
z->startcol = first_column;
z->endcol = last_column;
z->filename = strdup(my_file);
return z;
}
2006-04-27 18:09:20 +00:00
static struct pval *npval2(pvaltype type, YYLTYPE *first, YYLTYPE *last)
{
return npval(type, first->first_line, last->last_line,
first->first_column, last->last_column);
}
2006-04-26 22:41:16 +00:00
/* append second element to the list in the first one */
static void linku1(pval *head, pval *tail)
2006-04-24 17:41:27 +00:00
{
if (!head->next) {
head->next = tail;
} else {
head->u1_last->next = tail;
}
2006-04-26 22:41:16 +00:00
head->u1_last = tail;
2006-04-24 17:41:27 +00:00
}