2 * Copyright 2011 Jacek Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "wine/debug.h"
26 WINE_DEFAULT_DEBUG_CHANNEL
(vbscript
);
29 #define YYLEX_PARAM ctx
30 #define YYPARSE_PARAM ctx
32 static int parser_error
(const char*);
34 static void parse_complete
(parser_ctx_t
*);
36 static void source_add_statement
(parser_ctx_t
*,statement_t
*);
38 static expression_t
*new_bool_expression
(parser_ctx_t
*,VARIANT_BOOL
);
39 static expression_t
*new_string_expression
(parser_ctx_t
*,const WCHAR
*);
41 static member_expression_t
*new_member_expression
(parser_ctx_t
*,expression_t
*,const WCHAR
*);
43 static statement_t
*new_call_statement
(parser_ctx_t
*,member_expression_t
*);
45 #define CHECK_ERROR if(((parser_ctx_t*)ctx)->hres != S_OK) YYABORT
54 statement_t
*statement
;
55 expression_t
*expression
;
56 member_expression_t
*member
;
59 %token tEOF tNL tREM tEMPTYBRACKETS
61 %token tNOT tAND tOR tXOR tEQV tIMP tNEQ
62 %token tIS tLTEQ tGTEQ tMOD
63 %token tCALL tDIM tSUB tFUNCTION tPROPERTY tGET tLET
64 %token tIF tELSE tELSEIF tEND tTHEN tEXIT
65 %token tWHILE tWEND tDO tLOOP tUNTIL
67 %token tOPTION tEXPLICIT
69 %token tNOTHING tEMPTY tNULL
70 %token tCLASS tSET tNEW tPUBLIC tPRIVATE tDEFAULT tME
71 %token tERROR tNEXT tON tRESUME tGOTO
72 %token
<string> tIdentifier tString
74 %type
<statement
> Statement StatementNl
75 %type
<expression
> Expression LiteralExpression
76 %type
<member
> MemberExpression
77 %type
<expression
> Arguments_opt ArgumentList_opt ArgumentList
82 : SourceElements tEOF
{ parse_complete
(ctx
); }
86 | SourceElements StatementNl
{ source_add_statement
(ctx
, $2); }
89 : Statement tNL
{ $$
= $1; }
92 : MemberExpression ArgumentList_opt
{ $1->args
= $2; $$
= new_call_statement
(ctx
, $1); CHECK_ERROR
; }
93 | tCALL MemberExpression Arguments_opt
{ $2->args
= $3; $$
= new_call_statement
(ctx
, $2); CHECK_ERROR
; }
96 : tIdentifier
{ $$
= new_member_expression
(ctx
, NULL
, $1); CHECK_ERROR
; }
97 /* FIXME: MemberExpressionArgs '.' tIdentifier */
100 : EmptyBrackets_opt
{ $$
= NULL
; }
101 |
'(' ArgumentList
')' { $$
= $2; }
104 : EmptyBrackets_opt
{ $$
= NULL
; }
105 | ArgumentList
{ $$
= $1; }
108 : Expression
{ $$
= $1; }
109 | Expression
',' ArgumentList
{ $1->next
= $3; $$
= $1; }
116 : LiteralExpression
/* FIXME */ { $$
= $1; }
119 : tTRUE
{ $$
= new_bool_expression
(ctx
, VARIANT_TRUE
); CHECK_ERROR
; }
120 | tFALSE
{ $$
= new_bool_expression
(ctx
, VARIANT_FALSE
); CHECK_ERROR
; }
121 | tString
{ $$
= new_string_expression
(ctx
, $1); CHECK_ERROR
; }
125 static int parser_error
(const char *str
)
130 static void source_add_statement
(parser_ctx_t
*ctx
, statement_t
*stat
)
133 ctx
->stats_tail
->next
= stat
;
134 ctx
->stats_tail
= stat
;
136 ctx
->stats
= ctx
->stats_tail
= stat
;
140 static void parse_complete
(parser_ctx_t
*ctx
)
142 ctx
->parse_complete
= TRUE
;
145 static void *new_expression
(parser_ctx_t
*ctx
, expression_type_t type
, unsigned size
)
149 expr
= parser_alloc
(ctx
, size ? size
: sizeof
(*expr
));
158 static expression_t
*new_bool_expression
(parser_ctx_t
*ctx
, VARIANT_BOOL value
)
160 bool_expression_t
*expr
;
162 expr
= new_expression
(ctx
, EXPR_BOOL
, sizeof
(*expr
));
170 static expression_t
*new_string_expression
(parser_ctx_t
*ctx
, const WCHAR
*value
)
172 string_expression_t
*expr
;
174 expr
= new_expression
(ctx
, EXPR_STRING
, sizeof
(*expr
));
182 static member_expression_t
*new_member_expression
(parser_ctx_t
*ctx
, expression_t
*obj_expr
, const WCHAR
*identifier
)
184 member_expression_t
*expr
;
186 expr
= new_expression
(ctx
, EXPR_MEMBER
, sizeof
(*expr
));
190 expr
->obj_expr
= obj_expr
;
191 expr
->identifier
= identifier
;
196 static void *new_statement
(parser_ctx_t
*ctx
, statement_type_t type
, unsigned size
)
200 stat
= parser_alloc
(ctx
, size
);
209 static statement_t
*new_call_statement
(parser_ctx_t
*ctx
, member_expression_t
*expr
)
211 call_statement_t
*stat
;
213 stat
= new_statement
(ctx
, STAT_CALL
, sizeof
(*stat
));
221 void *parser_alloc
(parser_ctx_t
*ctx
, size_t size
)
226 ret
= heap_alloc
(size
);
228 ctx
->hres
= E_OUTOFMEMORY
;
232 HRESULT parse_script
(parser_ctx_t
*ctx
, const WCHAR
*code
)
234 ctx
->code
= ctx
->ptr
= code
;
235 ctx
->end
= ctx
->code
+ strlenW
(ctx
->code
);
237 ctx
->parse_complete
= FALSE
;
240 ctx
->last_token
= tNL
;
242 ctx
->stats
= ctx
->stats_tail
= NULL
;
246 if
(FAILED
(ctx
->hres
))
248 if
(!ctx
->parse_complete
) {
249 FIXME
("parser failed on parsing %s\n", debugstr_w
(ctx
->ptr
));