aboutsummaryrefslogtreecommitdiff
path: root/src/build.l
blob: 41abaf4e91c22613bd5539b46012f592dd368864 (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
%{
# include <string>
# include "buildparser.h"
# include "build.tab.h"
# include "stringrep.h"

std::string strbuf;
%}

%x strsq
%x strdq
%x comment
%option noyywrap nounput batch debug

%{
# define YY_USER_ACTION  yylloc->last_column += yyleng;
%}
%%

[,:=[\]()]							return yytext[0];
"+="								return TOK_ADDSET;

"default"							return TOK_DEFAULT;
"action"							return TOK_ACTION;
"rule"								return TOK_RULE;
"requires"							return TOK_REQUIRES;
"set"								return TOK_SET;
"matches"							return TOK_MATCHES;
"perform"							return TOK_PERFORM;
"produces"							return TOK_PRODUCES;
"check"								return TOK_CHECK;
"clean"								return TOK_CLEAN;
"target"							return TOK_TARGET;
"input"								return TOK_INPUT;
"filter"							return TOK_FILTER;
"prefix"							return TOK_PREFIX;

\n+									{
	yylloc->last_line += yyleng;
	yylloc->first_line = yylloc->last_line;
	yylloc->first_column = yylloc->last_column = 0;
}

[ \t\r]*							{
	yylloc->first_line = yylloc->last_line;
	yylloc->first_column = yylloc->last_column+1;
}

"#".*								/* single line comment */

[a-zA-Z][a-zA-Z0-9]*						{
	{
		if( bld.isTarget( yytext ) )
		{
			yylval->strval = stringdup( yytext );
			return TARGETTYPE;
		}
		else if( bld.isPerform( yytext ) )
		{
			yylval->strval = stringdup( yytext );
			return PERFORM;
		}
		else if( bld.isFunction( yytext ) )
		{
			yylval->strval = stringdup( yytext );
			return FUNCTION;
		}
		bld.error( yylloc, "Invalid token" );
	}
}

\"									{
	BEGIN( strdq );
	strbuf = "";
}
\'									{
	BEGIN( strsq );
	strbuf = "";
}

<strdq>[^\\\n\"]+					{
	strbuf += yytext;
}

<strsq>[^\\\n\']+					{
	strbuf += yytext;
}

<strdq,strsq>\\n					strbuf += "\n";
<strdq,strsq>\\t					strbuf += "\t";
<strdq,strsq>\\r					strbuf += "\r";
<strdq,strsq>\\b					strbuf += "\b";
<strdq,strsq>\\f					strbuf += "\f";
<strdq,strsq>\\\\					strbuf += "\\";
<strdq,strsq>\\\"					strbuf += "\"";
<strdq,strsq>\\\'					strbuf += "\'";
<strdq,strsq>\\.					bld.error( yylloc, "Invalid escape sequence.");

<strdq>\"							{
	BEGIN( INITIAL );
	yylval->strval = stringdup( strbuf.c_str() );
	return STRING;
}

<strsq>\'							{
	BEGIN( INITIAL );
	yylval->strval = stringdup( strbuf.c_str() );
	return STRING;
}

.									{
	char buf[] = {"Character x is out of place"};
	buf[10] = yytext[0];
	bld.error( yylloc, buf );
}

%%

void BuildParser::scanBegin()
{
	yy_flex_debug = false;
	if( !(yyin = fopen( file.c_str(), "r" )) )
	{
		error( std::string("cannot open file: ") + file );
	}
}

void BuildParser::scanEnd()
{
	fclose( yyin );
}