summaryrefslogtreecommitdiff
path: root/src/nsgenbind-lexer.l
blob: af773687561a00168a1857047f7d45a806e1e3c5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
%{

/* lexer for the binding generation config file 
 *
 * This file is part of nsgenbind.
 * Licensed under the MIT License,
 *                http://www.opensource.org/licenses/mit-license.php
 * Copyright 2012 Vincent Sanders <vince@netsurf-browser.org>
 */

#include <stdbool.h>
#include <stdio.h>
#include <string.h>

#include "nsgenbind-parser.h"
#include "nsgenbind-ast.h"

#define YY_USER_ACTION                                             \
        yylloc->first_line = yylloc->last_line = yylineno;         \
        yylloc->first_column = yylloc->last_column + 1;            \
        yylloc->last_column += yyleng;


/* Ensure compatability with bison 2.6 and later */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED && defined NSGENBIND_STYPE_IS_DECLARED
#define YYSTYPE NSGENBIND_STYPE
#endif

#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED && defined NSGENBIND_LTYPE_IS_DECLARED
#define YYLTYPE NSGENBIND_LTYPE
#endif

static struct YYLTYPE *locations = NULL;

static struct YYLTYPE *push_location(struct YYLTYPE *head,
                                     struct YYLTYPE *loc,
                                     const char *filename)
{
        struct YYLTYPE *res;
        res = calloc(1, sizeof(struct YYLTYPE));
        /* copy current location and line number */
        *res = *loc;
        res->start_line = yylineno;
        res->next = head;

        /* reset current location */
        loc->first_line = loc->last_line = 1;
        loc->first_column = loc->last_column = 1;
        loc->filename = strdup(filename);
        yylineno = 1;

        return res;
}

static struct YYLTYPE *pop_location(struct YYLTYPE *head, struct YYLTYPE *loc)
{
        struct YYLTYPE *res = NULL;

        if (head != NULL) {
                res = head->next;
                *loc = *head;
                free(head);

                yylineno = loc->start_line;
        }
        return res;
}


%}

/* lexer options */
%option never-interactive
%option yylineno
%option bison-bridge
%option bison-locations
%option nodefault
%option warn
%option prefix="nsgenbind_"
%option nounput
%option noinput
%option noyywrap

/* other Unicode “space separator” */
USP (\xe1\x9a\x80)|(\xe1\xa0\x8e)|(\xe2\x80[\x80-\x8a])|(\xe2\x80\xaf)|(\xe2\x81\x9f)|(\xe3\x80\x80)

/* non breaking space \u00A0 */
NBSP (\xc2\xa0)

/* Line separator \u2028 */
LS (\xe2\x80\xa8)

/* paragraph separator \u2029 */
PS (\xe2\x80\xa9)

whitespace              ([ \t\v\f]|{NBSP}|{USP})

lineend                 ([\n\r]|{LS}|{PS})

multicomment            \/\*(([^*])|(\*[^/]))*\*\/

quotedstring            [^\"\\\n\r]

identifier              [A-Z_a-z][0-9A-Z_a-z]*

other                   [^\t\n\r 0-9A-Z_a-z]

cblockopen              \%\{

cblockclose             \%\}

/* used for #include directive */
poundsign               ^{whitespace}*#

dblcolon                \:\:

%x                      cblock

%x                      incl

%%

{whitespace}            ++yylloc->last_column;/* nothing */

{lineend}               if (yytext[0] != '\r') {
                            /* update position counts */
                            ++yylloc->last_line;
                            yylloc->last_column = 0;
                        }

 /* binding terminals */

binding                 return TOK_BINDING;
webidl                  return TOK_WEBIDL;
preface                 return TOK_PREFACE;
prologue                return TOK_PROLOGUE;
epilogue                return TOK_EPILOGUE;
postface                return TOK_POSTFACE;


 /* class member terminals */

class                   return TOK_CLASS;
private                 return TOK_PRIVATE;
internal                return TOK_INTERNAL;
flags                   return TOK_FLAGS;
type                    return TOK_TYPE;
unshared                return TOK_UNSHARED;
shared                  return TOK_SHARED;
property                return TOK_PROPERTY;

 /* implementation terminals */

init                    return TOK_INIT;
fini                    return TOK_FINI;
method                  return TOK_METHOD;
getter                  return TOK_GETTER;
setter                  return TOK_SETTER;
prototype               return TOK_PROTOTYPE;

 /* c type terminals */

struct                  return TOK_STRUCT;
union                   return TOK_UNION;
unsigned                return TOK_UNSIGNED;

 /* other terminals */

{dblcolon}              return TOK_DBLCOLON;

{cblockopen}            BEGIN(cblock);

{identifier}        {
                        /* A leading "_" is used to escape an identifier from 
                         *   looking like a reserved word terminal.
                         */
                        yylval->text = (yytext[0] == '_') ? strdup(yytext + 1) : strdup(yytext);
                        return TOK_IDENTIFIER;
                    }

\"{quotedstring}*\"     yylval->text = strndup(yytext + 1, yyleng - 2 ); return TOK_STRING_LITERAL;

{multicomment}          /* nothing */

{poundsign}include      BEGIN(incl);

{other}                 return (int) yytext[0];

.                       /* nothing */

<cblock>[^\%]*          yylval->text = strdup(yytext); return TOK_CCODE_LITERAL;
<cblock>{cblockclose}   BEGIN(INITIAL);
<cblock>\%              yylval->text = strdup(yytext); return TOK_CCODE_LITERAL;


<incl>[ \t]*\"          /* eat the whitespace and open quotes */

<incl>[^\t\n\"]+    { 
                        /* got the include file name */
                        yyin = genbindopen(yytext);
     
                        if (! yyin) {
                            fprintf(stderr, "Unable to open include %s\n", yytext);
                            exit(3);
                        }

                        locations = push_location(locations, yylloc, yytext);

                        yypush_buffer_state(yy_create_buffer(yyin, YY_BUF_SIZE));
                        BEGIN(INITIAL);
                    }

<incl>\n                BEGIN(INITIAL);

<incl>.                 /* nothing */

<<EOF>>             {
     			yypop_buffer_state();
     
                        if ( !YY_CURRENT_BUFFER ) {
                                yyterminate();
                        } else {
                                locations = pop_location(locations, yylloc);
                                BEGIN(incl);
                        }

                    }

%%