1
2/*
3  +------------------------------------------------------------------------+
4  | Phalcon Framework                                                      |
5  +------------------------------------------------------------------------+
6  | Copyright (c) 2011-2016 Phalcon Team (http://www.phalconphp.com)       |
7  +------------------------------------------------------------------------+
8  | This source file is subject to the New BSD License that is bundled     |
9  | with this package in the file docs/LICENSE.txt.                        |
10  |                                                                        |
11  | If you did not receive a copy of the license and are unable to         |
12  | obtain it through the world-wide-web, please send an email             |
13  | to license@phalconphp.com so we can send you a copy immediately.       |
14  +------------------------------------------------------------------------+
15  | Authors: Andres Gutierrez <andres@phalconphp.com>                      |
16  |          Eduar Carvajal <eduar@phalconphp.com>                         |
17  +------------------------------------------------------------------------+
18*/
19
20%token_prefix PHANNOT_
21%token_type {phannot_parser_token*}
22%default_type {zval*}
23%extra_argument {phannot_parser_status *status}
24%name phannot_
25
26%left COMMA .
27
28%include {
29#include "parser.php5.inc.h"
30}
31
32%syntax_error {
33	if (status->scanner_state->start_length) {
34		char *token_name = NULL;
35		const phannot_token_names *tokens = phannot_tokens;
36		uint active_token = status->scanner_state->active_token;
37		uint near_length = status->scanner_state->start_length;
38
39		if (active_token) {
40			do {
41				if (tokens->code == active_token) {
42					token_name = tokens->name;
43					break;
44				}
45				++tokens;
46			} while (tokens[0].code != 0);
47		}
48
49		if (!token_name) {
50			token_name  = "UNKNOWN";
51		}
52
53		if (near_length > 0) {
54			if (status->token->value) {
55				spprintf(&status->syntax_error, 0, "Syntax error, unexpected token %s(%s), near to '%s' in %s on line %d", token_name, status->token->value, status->scanner_state->start, status->scanner_state->active_file, status->scanner_state->active_line);
56			} else {
57				spprintf(&status->syntax_error, 0, "Syntax error, unexpected token %s, near to '%s' in %s on line %d", token_name, status->scanner_state->start, status->scanner_state->active_file, status->scanner_state->active_line);
58			}
59		} else {
60			if (active_token != PHANNOT_T_IGNORE) {
61				if (status->token->value) {
62					spprintf(&status->syntax_error, 0, "Syntax error, unexpected token %s(%s), at the end of docblock in %s on line %d", token_name, status->token->value, status->scanner_state->active_file, status->scanner_state->active_line);
63				} else {
64					spprintf(&status->syntax_error, 0, "Syntax error, unexpected token %s, at the end of docblock in %s on line %d", token_name, status->scanner_state->active_file, status->scanner_state->active_line);
65				}
66			} else {
67				spprintf(&status->syntax_error, 0, "Syntax error, unexpected EOF, at the end of docblock in %s on line %d", status->scanner_state->active_file, status->scanner_state->active_line);
68			}
69		}
70	} else {
71		spprintf(&status->syntax_error, 0, "Syntax error, unexpected EOF in %s", status->scanner_state->active_file);
72	}
73
74	status->status = PHANNOT_PARSING_FAILED;
75}
76
77%token_destructor {
78	if ($$) {
79		if ($$->free_flag) {
80			efree($$->token);
81		}
82		efree($$);
83	}
84}
85
86program ::= annotation_language(Q) . {
87	status->ret = Q;
88}
89
90%destructor annotation_language {
91    zval_ptr_dtor(&$$);
92}
93
94annotation_language(R) ::= annotation_list(L) . {
95	R = L;
96}
97
98%destructor annotation_list {
99    zval_ptr_dtor(&$$);
100}
101
102annotation_list(R) ::= annotation_list(L) annotation(S) . {
103	R = phannot_ret_zval_list(L, S);
104}
105
106annotation_list(R) ::= annotation(S) . {
107	R = phannot_ret_zval_list(NULL, S);
108}
109
110%destructor annotation {
111    zval_ptr_dtor(&$$);
112}
113
114annotation(R) ::= AT IDENTIFIER(I) PARENTHESES_OPEN argument_list(L) PARENTHESES_CLOSE . {
115	R = phannot_ret_annotation(I, L, status->scanner_state);
116}
117
118annotation(R) ::= AT IDENTIFIER(I) PARENTHESES_OPEN PARENTHESES_CLOSE . {
119	R = phannot_ret_annotation(I, NULL, status->scanner_state);
120}
121
122annotation(R) ::= AT IDENTIFIER(I) . {
123	R = phannot_ret_annotation(I, NULL, status->scanner_state);
124}
125
126%destructor argument_list {
127    zval_ptr_dtor(&$$);
128}
129
130argument_list(R) ::= argument_list(L) COMMA argument_item(I) . {
131	R = phannot_ret_zval_list(L, I);
132}
133
134argument_list(R) ::= argument_item(I) . {
135	R = phannot_ret_zval_list(NULL, I);
136}
137
138%destructor argument_item {
139    zval_ptr_dtor(&$$);
140}
141
142argument_item(R) ::= expr(E) . {
143	R = phannot_ret_named_item(NULL, E);
144}
145
146argument_item(R) ::= STRING(S) EQUALS expr(E) . {
147	R = phannot_ret_named_item(S, E);
148}
149
150argument_item(R) ::= STRING(S) COLON expr(E) . {
151	R = phannot_ret_named_item(S, E);
152}
153
154argument_item(R) ::= IDENTIFIER(I) EQUALS expr(E) . {
155	R = phannot_ret_named_item(I, E);
156}
157
158argument_item(R) ::= IDENTIFIER(I) COLON expr(E) . {
159	R = phannot_ret_named_item(I, E);
160}
161
162%destructor expr {
163    zval_ptr_dtor(&$$);
164}
165
166expr(R) ::= annotation(S) . {
167	R = S;
168}
169
170expr(R) ::= array(A) . {
171	R = A;
172}
173
174expr(R) ::= IDENTIFIER(I) . {
175	R = phannot_ret_literal_zval(PHANNOT_T_IDENTIFIER, I);
176}
177
178expr(R) ::= INTEGER(I) . {
179	R = phannot_ret_literal_zval(PHANNOT_T_INTEGER, I);
180}
181
182expr(R) ::= STRING(S) . {
183	R = phannot_ret_literal_zval(PHANNOT_T_STRING, S);
184}
185
186expr(R) ::= DOUBLE(D) . {
187	R = phannot_ret_literal_zval(PHANNOT_T_DOUBLE, D);
188}
189
190expr(R) ::= NULL . {
191	R = phannot_ret_literal_zval(PHANNOT_T_NULL, NULL);
192}
193
194expr(R) ::= FALSE . {
195	R = phannot_ret_literal_zval(PHANNOT_T_FALSE, NULL);
196}
197
198expr(R) ::= TRUE . {
199	R = phannot_ret_literal_zval(PHANNOT_T_TRUE, NULL);
200}
201
202array(R) ::= BRACKET_OPEN argument_list(A) BRACKET_CLOSE . {
203	R = phannot_ret_array(A);
204}
205
206array(R) ::= SBRACKET_OPEN argument_list(A) SBRACKET_CLOSE . {
207	R = phannot_ret_array(A);
208}
209