1 : %option reentrant bison-bridge bison-locations
2 : %option noyywrap
3 : %option never-interactive
4 :
5 :
6 : %x STRING
7 :
8 :
9 : %{
10 : #include "aterm.hh"
11 : #include "nixexpr.hh"
12 : #include "nixexpr-ast.hh"
13 : #define BISON_HEADER_HACK
14 : #include "parser-tab.hh"
15 :
16 : using namespace nix;
17 :
18 : namespace nix {
19 :
20 :
21 : static void initLoc(YYLTYPE * loc)
22 99 : {
23 99 : loc->first_line = 1;
24 99 : loc->first_column = 1;
25 : }
26 :
27 :
28 : static void adjustLoc(YYLTYPE * loc, const char * s, size_t len)
29 52292 : {
30 52292 : while (len--) {
31 41281 : switch (*s++) {
32 : case '\r':
33 6 : if (*s == '\n') /* cr/lf */
34 3 : s++;
35 : /* fall through */
36 : case '\n':
37 1405 : ++loc->first_line;
38 1405 : loc->first_column = 1;
39 1405 : break;
40 : default:
41 39876 : ++loc->first_column;
42 : }
43 : }
44 : }
45 :
46 :
47 : static Expr unescapeStr(const char * s)
48 734 : {
49 734 : string t;
50 16581 : char c;
51 16581 : while ((c = *s++)) {
52 15847 : if (c == '\\') {
53 5 : assert(*s);
54 5 : c = *s++;
55 5 : if (c == 'n') t += '\n';
56 4 : else if (c == 'r') t += '\r';
57 3 : else if (c == 't') t += '\t';
58 3 : else t += c;
59 : }
60 15842 : else if (c == '\r') {
61 : /* Normalise CR and CR/LF into LF. */
62 2 : t += '\n';
63 2 : if (*s == '\n') s++; /* cr/lf */
64 : }
65 15840 : else t += c;
66 : }
67 734 : return makeStr(toATerm(t));
68 : }
69 :
70 :
71 : }
72 :
73 : #define YY_USER_INIT initLoc(yylloc)
74 : #define YY_USER_ACTION adjustLoc(yylloc, yytext, yyleng);
75 :
76 : %}
77 :
78 :
79 : ID [a-zA-Z\_][a-zA-Z0-9\_\']*
80 : INT [0-9]+
81 : PATH [a-zA-Z0-9\.\_\-\+]*(\/[a-zA-Z0-9\.\_\-\+]+)+
82 : URI [a-zA-Z][a-zA-Z0-9\+\-\.]*\:[a-zA-Z0-9\%\/\?\:\@\&\=\+\$\,\-\_\.\!\~\*\']+
83 :
84 :
85 : %%
86 :
87 :
88 27 : if { return IF; }
89 54 : then { return THEN; }
90 54 : else { return ELSE; }
91 71 : assert { return ASSERT; }
92 37 : with { return WITH; }
93 114 : let { return LET; }
94 9 : in { return IN; }
95 76 : rec { return REC; }
96 60 : inherit { return INHERIT; }
97 32 :
98 46 : \=\= { return EQ; }
99 33 : \!\= { return NEQ; }
100 14 : \&\& { return AND; }
101 12 : \|\| { return OR; }
102 23 : \-\> { return IMPL; }
103 28 : \/\/ { return UPDATE; }
104 22 : \+\+ { return CONCAT; }
105 1572 :
106 1566 : {ID} { yylval->t = toATerm(yytext); return ID; /* !!! alloc */ }
107 1673 : {INT} { int n = atoi(yytext); /* !!! overflow */
108 57 : yylval->t = ATmake("<int>", n);
109 114 : return INT;
110 : }
111 740 :
112 740 : \" { BEGIN(STRING); return '"'; }
113 1474 : <STRING>([^\$\"\\]|\$[^\{\"]|\\.)+ {
114 : /* !!! Not quite right: we want a follow restriction on "$", it
115 : shouldn't be followed by a "{". Right now "$\"" will be consumed
116 734 : as part of a string, rather than a "$" followed by the string
117 : terminator. Disallow "$\"" for now. */
118 734 : yylval->t = unescapeStr(yytext); /* !!! alloc */
119 734 : return STR;
120 : }
121 4 : <STRING>\$\{ { BEGIN(INITIAL); return DOLLAR_CURLY; }
122 1480 : <STRING>\" { BEGIN(INITIAL); return '"'; }
123 2 : <STRING>. return yytext[0]; /* just in case: shouldn't be reached */
124 740 :
125 0 :
126 128 : {PATH} { yylval->t = toATerm(yytext); return PATH; /* !!! alloc */ }
127 16 : {URI} { yylval->t = toATerm(yytext); return URI; /* !!! alloc */ }
128 3915 :
129 8 : [ \t\r\n]+ /* eat up whitespace */
130 3915 : \#[^\r\n]* /* single-line comments */
131 3952 : \/\*([^*]|\*[^\/])*\*\/ /* long comments */
132 41 :
133 2825 : . return yytext[0];
134 2829 :
135 :
136 0 : %%
137 0 :
138 :
139 : namespace nix {
140 :
141 : /* Horrible, disgusting hack: allow the parser to set the scanner
142 : start condition back to STRING. Necessary in interpolations like
143 : "foo${expr}bar"; after the close brace we have to go back to the
144 : STRING state. */
145 : void backToString(yyscan_t scanner)
146 : {
147 2 : struct yyguts_t * yyg = (struct yyguts_t *) scanner;
148 2 : BEGIN(STRING);
149 2 : }
150 :
151 : }
|