aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Ankarström <john@ankarstrom.se>2022-06-10 18:03:44 +0200
committerJohn Ankarström <john@ankarstrom.se>2022-06-10 18:03:44 +0200
commit392fc74a77b94cc78e9bfe349dcdfa0ab8fc8f5c (patch)
treeb8c2a2ad562958ee21751437938194c9aa62584c
downloadlightroff-392fc74a77b94cc78e9bfe349dcdfa0ab8fc8f5c.tar.gz
Simple lex implementation.
-rw-r--r--.gitignore6
-rw-r--r--Makefile7
-rw-r--r--xroff.lex69
3 files changed, 82 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..f22fb6c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+*~
+lex.yy.c
+xroff
+xroff.exe
+*.pdf
+*.ps
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..80cc949
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,7 @@
+CC = gcc
+
+xroff: lex.yy.c
+ $(CC) $(CFLAGS) $(LDFLAGS) -o xroff lex.yy.c
+
+lex.yy.c: xroff.lex
+ flex xroff.lex
diff --git a/xroff.lex b/xroff.lex
new file mode 100644
index 0000000..6282ca1
--- /dev/null
+++ b/xroff.lex
@@ -0,0 +1,69 @@
+%option noyywrap
+%x NEW
+%x REQ
+%x RAW
+%x ESC
+%x RES
+
+%%
+
+\\ BEGIN(ESC);
+\n BEGIN(NEW);
+\<!\[ BEGIN(RAW);
+^< printf("."); BEGIN(REQ); /* Beginning of file. */
+\< printf("\\c\n."); BEGIN(REQ);
+. ECHO;
+
+ /* Handle text following newlines. */
+
+<NEW>\n /* Ignore consecutive newlines. */
+<NEW>\\ printf("\n"); BEGIN(ESC);
+<NEW>\<!\[\n? printf("\n"); BEGIN(RAW);
+<NEW>< printf("\n."); BEGIN(REQ);
+<NEW>\. printf("\n\\&."); BEGIN(0);
+<NEW>. printf("\n"); BEGIN(0); REJECT;
+
+ /* Translate request. */
+
+<REQ>\\ BEGIN(RES);
+<REQ>> BEGIN(NEW);
+
+ /* Pass through raw troff code. */
+
+<RAW>\n\]> BEGIN(NEW);
+<RAW>\]> BEGIN(0);
+<RAW>. ECHO;
+
+ /* Escape next character. */
+
+<ESC>\\ printf("\\\\"); BEGIN(0);
+<ESC>< ECHO; BEGIN(0);
+<ESC>. printf("\\"); ECHO; BEGIN(0);
+
+ /* Escape next character within request. */
+
+<RES>\\ printf("\\\\"); BEGIN(REQ);
+<RES>> ECHO; BEGIN(REQ);
+<RES>. printf("\\"); ECHO; BEGIN(REQ);
+
+%%
+
+int
+main()
+{
+ char *st;
+
+ yylex();
+
+ switch (YYSTATE) {
+ case 0: return 0;
+ case NEW: printf("\n"); return 0;
+ case REQ: st = "request"; break;
+ case RAW: st = "raw section"; break;
+ case ESC: st = "escape"; break;
+ case RES: st = "escape (within request)"; break;
+ }
+
+ fprintf(stderr, "%s unfinished\n", st);
+ return 1;
+}