summary refs log tree commit diff
path: root/bin/hilex/make.l
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2020-12-29 22:39:16 -0500
committerJune McEnroe <june@causal.agency>2020-12-29 22:39:16 -0500
commit7c70322c7c8e88af93375b89146b0cd6cb8cc7f0 (patch)
tree109495ff8c3b181f871d38d8b5d34835d23a185c /bin/hilex/make.l
parentClean up C lexer (diff)
downloadsrc-7c70322c7c8e88af93375b89146b0cd6cb8cc7f0.tar.gz
src-7c70322c7c8e88af93375b89146b0cd6cb8cc7f0.zip
Add make lexer
This is kind of a mess and needs to be cleaned up against more careful
reading of the make grammar.
Diffstat (limited to 'bin/hilex/make.l')
-rw-r--r--bin/hilex/make.l102
1 files changed, 102 insertions, 0 deletions
diff --git a/bin/hilex/make.l b/bin/hilex/make.l
new file mode 100644
index 00000000..e7961eb8
--- /dev/null
+++ b/bin/hilex/make.l
@@ -0,0 +1,102 @@
+/* Copyright (C) 2020  C. McEnroe <june@causal.agency>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+%option prefix="make"
+%option noyywrap
+
+%{
+#include "hilex.h"
+%}
+
+%s Assign
+%x Interp Shell
+
+ident [._[:alnum:]]+
+target [-/._[:alnum:]]+
+assign [!+:?]?=
+
+%%
+	static int pop = INITIAL;
+	static int depth = 0;
+
+^"\t" {
+	BEGIN(pop = Shell);
+	return Normal;
+}
+<Shell>{
+	"\n" {
+		BEGIN(pop = INITIAL);
+		return Normal;
+	}
+	[^\n$]+|. { return Normal; }
+}
+
+[[:blank:]] { return Normal; }
+
+"."(PHONY|PRECIOUS|SUFFIXES)/":"? {
+	return Keyword;
+}
+
+^{ident}/[[:blank:]]*{assign} {
+	return Identifier;
+}
+
+{assign} {
+	BEGIN(pop = Assign);
+	return Operator;
+}
+<Assign>{
+	"\n" {
+		BEGIN(pop = INITIAL);
+		return Normal;
+	}
+	[^$[:space:]]+ { return String; }
+}
+
+{target}([[:blank:]]+{target})*/":" {
+	return IdentifierTag;
+}
+
+^"-"?include { return Macro; }
+
+"#".* { return Comment; }
+
+<*>{
+	"$"("{"|"(") {
+		depth++;
+		BEGIN(Interp);
+		return Interpolation;
+	}
+	"$". { return Interpolation; }
+}
+<Interp>{
+	"}"|")" {
+		if (!--depth) BEGIN(pop);
+		return Interpolation;
+	}
+	[^${}()]+ { return Interpolation; }
+}
+
+.|\n { return Normal; }
+
+%{
+	(void)yyunput;
+	(void)input;
+%}
+
+%%
+
+const struct Lexer LexMake = { yylex, &yyin, &yytext };