diff --git a/NEWS b/NEWS
index 9c49fe84..3b714d6a 100644
--- a/NEWS
+++ b/NEWS
@@ -142,7 +142,8 @@ GNU Bison NEWS
README and a Makefile. Not only can they be used to toy with Bison, they
can also be starting points for your own grammars.
- There is now a Java example.
+ There is now a Java example, and a simple example in C based on Flex and
+ Bison (examples/c/lexcalc/).
** Changes
diff --git a/examples/c++/calc++/README.md b/examples/c++/calc++/README.md
index d4d5154f..02e0d681 100644
--- a/examples/c++/calc++/README.md
+++ b/examples/c++/calc++/README.md
@@ -1,6 +1,10 @@
-This directory contains calc++, a simple Bison grammar file in C++.
+# calc++ - A Flex+Bison calculator
-Please, read the corresponding chapter in the documentation: "A Complete C++
+This directory contains calc++, a Bison grammar file in C++. If you never
+saw the traditional implementation in C, please first read
+examples/c/lexcalc, which can be seen as a C precursor of this example.
+
+Read the corresponding chapter in the documentation: "A Complete C++
Example". It is also available on line (maybe with a different version of
Bison):
https://www.gnu.org/software/bison/manual/html_node/A-Complete-C_002b_002b-Example.html
@@ -27,7 +31,6 @@ You may pass `-p` to activate the parser debug traces, and `-s` to activate
the scanner's.
diff --git a/examples/c/lexcalc/Makefile b/examples/c/lexcalc/Makefile
new file mode 100644
index 00000000..e7c798cd
--- /dev/null
+++ b/examples/c/lexcalc/Makefile
@@ -0,0 +1,34 @@
+# This Makefile is designed to be simple and readable. It does not
+# aim at portability. It requires GNU Make.
+
+BASE = lexcalc
+BISON = bison
+FLEX = flex
+XSLTPROC = xsltproc
+
+all: $(BASE)
+
+%.c %.h %.xml %.gv: %.y
+ $(BISON) $(BISONFLAGS) --defines --xml --graph=$*.gv -o $*.c $<
+
+%.c: %.l
+ $(FLEX) $(FLEXFLAGS) -o$@ $<
+
+scan.o: parse.h
+lexcalc: parse.o scan.o
+ $(CC) $(CFLAGS) -o $@ $^
+
+run: $(BASE)
+ @echo "Type arithmetic expressions. Quit with ctrl-d."
+ ./$<
+
+html: parse.html
+%.html: %.xml
+ $(XSLTPROC) $(XSLTPROCFLAGS) -o $@ $$($(BISON) --print-datadir)/xslt/xml2xhtml.xsl $<
+
+CLEANFILES = \
+ $(BASE) *.o \
+ parse.[ch] parse.output parse.xml parse.html parse.gv \
+ scan.c
+clean:
+ rm -f $(CLEANFILES)
diff --git a/examples/c/lexcalc/README.md b/examples/c/lexcalc/README.md
new file mode 100644
index 00000000..32e6d534
--- /dev/null
+++ b/examples/c/lexcalc/README.md
@@ -0,0 +1,28 @@
+# lexcalc - calculator with Flex and Bison
+
+This directory contains lexcalc, the traditional example of using Flex and
+Bison to build a simple calculator.
+
+
diff --git a/examples/c/lexcalc/lexcalc.test b/examples/c/lexcalc/lexcalc.test
new file mode 100644
index 00000000..0df4e38c
--- /dev/null
+++ b/examples/c/lexcalc/lexcalc.test
@@ -0,0 +1,27 @@
+#! /bin/sh
+
+# Copyright (C) 2018 Free Software Foundation, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+cat >input <input <.
+
+lexcalcdir = $(docdir)/%D%
+
+## ------ ##
+## Calc. ##
+## ------ ##
+
+check_PROGRAMS += %D%/lexcalc
+TESTS += %D%/lexcalc.test
+EXTRA_DIST += %D%/lexcalc.test
+%C%_lexcalc_SOURCES = %D%/parse.y %D%/parse.h %D%/scan.l
+
+# Don't use gnulib's system headers.
+%C%_lexcalc_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D%
+
+dist_lexcalc_DATA = %D%/parse.y %D%/scan.l %D%/Makefile %D%/README.md
+CLEANFILES += %D%/lexcalc %D%/*.o %D%/parse.c %D%/scan.c
+CLEANDIRS += %D%/*.dSYM
diff --git a/examples/c/lexcalc/parse.y b/examples/c/lexcalc/parse.y
new file mode 100644
index 00000000..5306de30
--- /dev/null
+++ b/examples/c/lexcalc/parse.y
@@ -0,0 +1,95 @@
+// Prologue (directives).
+%expect 0
+
+// Emitted in the header file, after the definition of YYSTYPE.
+%code provides
+{
+ // Tell Flex the expected prototype of yylex.
+#define YY_DECL \
+ enum yytokentype yylex (YYSTYPE* yylval, int *nerrs)
+ YY_DECL;
+
+ void yyerror (int *nerrs, const char *msg);
+}
+
+// Emitted on top of the implementation file.
+%code top
+{
+#include /* printf. */
+#include /* getenv. */
+}
+
+%define api.pure full
+%define api.token.prefix {TOK_}
+%define api.value.type union
+%define parse.error verbose
+%define parse.trace
+ // Error count, exchanged between main, yyparse and yylex.
+%param {int *nerrs}
+
+%token
+ PLUS "+"
+ MINUS "-"
+ STAR "*"
+ SLASH "/"
+ LPAREN "("
+ RPAREN ")"
+ EOL "end-of-line"
+ EOF 0 "end-of-file"
+;
+
+%token NUM "number"
+%type exp line
+%printer { fprintf (yyo, "%d", $$); }
+
+// Precedence (from lowest to highest) and associativity.
+%left "+" "-"
+%left "*" "/"
+
+%%
+// Rules.
+input:
+ %empty
+| input line { printf ("%d\n", $line); }
+;
+
+line:
+ exp EOL { $$ = $1; }
+| error EOL { yyerrok; }
+;
+
+exp:
+ exp "+" exp { $$ = $1 + $3; }
+| exp "-" exp { $$ = $1 - $3; }
+| exp "*" exp { $$ = $1 * $3; }
+| exp "/" exp
+ {
+ if ($3 == 0)
+ {
+ yyerror (nerrs, "invalid division by zero");
+ YYERROR;
+ }
+ else
+ $$ = $1 / $3;
+ }
+| "(" exp ")" { $$ = $2; }
+| NUM { $$ = $1; }
+;
+%%
+// Epilogue (C code).
+void yyerror(int *nerrs, const char *msg)
+{
+ fprintf (stderr, "%s\n", msg);
+ ++nerrs;
+}
+
+int main (void)
+{
+ int nerrs = 0;
+ // Enable parser runtime debugging.
+ if (!!getenv ("YYDEBUG"))
+ yydebug = 1;
+ yyparse (&nerrs);
+ // Exit on failure if there were errors.
+ return !!nerrs;
+}
diff --git a/examples/c/lexcalc/scan.l b/examples/c/lexcalc/scan.l
new file mode 100644
index 00000000..fc73f3b0
--- /dev/null
+++ b/examples/c/lexcalc/scan.l
@@ -0,0 +1,43 @@
+/* Prologue (directives). -*- C++ -*- */
+
+/* Disable Flex features we don't need, to avoid warnings. */
+%option nodefault noinput nounput noyywrap
+
+%{
+#include /* INT_MIN */
+#include /* strtol */
+
+#include "parse.h"
+%}
+
+%%
+ /* Rules. */
+
+"+" return TOK_PLUS;
+"-" return TOK_MINUS;
+"*" return TOK_STAR;
+"/" return TOK_SLASH;
+
+"(" return TOK_LPAREN;
+")" return TOK_RPAREN;
+
+ /* Scan an integer. */
+[0-9]+ {
+ errno = 0;
+ long n = strtol (yytext, NULL, 10);
+ if (! (INT_MIN <= n && n <= INT_MAX && errno != ERANGE))
+ yyerror (nerrs, "integer is out of range");
+ yylval->TOK_NUM = (int) n;
+ return TOK_NUM;
+}
+
+ /* Ignore white spaces. */
+[ \t]+ continue;
+
+"\n" return TOK_EOL;
+
+. yyerror (nerrs, "syntax error, invalid character");
+
+<> return TOK_EOF;
+%%
+/* Epilogue (C code). */
diff --git a/examples/c/local.mk b/examples/c/local.mk
index dcd90424..fb1c33d1 100644
--- a/examples/c/local.mk
+++ b/examples/c/local.mk
@@ -16,5 +16,6 @@
cdir = $(docdir)/%D%
dist_c_DATA = %D%/README.md
+include %D%/lexcalc/local.mk
include %D%/mfcalc/local.mk
include %D%/rpcalc/local.mk
diff --git a/examples/c/rpcalc/Makefile b/examples/c/rpcalc/Makefile
index 87e18f34..624f247b 100644
--- a/examples/c/rpcalc/Makefile
+++ b/examples/c/rpcalc/Makefile
@@ -14,7 +14,7 @@ all: $(BASE)
$(CC) $(CFLAGS) -o $@ $<
run: $(BASE)
- @echo "Type arithmetic expressions in reverse polish notation. Quit with ctrl-d."
+ @echo "Type arithmetic expressions in Reverse Polish Notation. Quit with ctrl-d."
./$<
html: $(BASE).html