Hi Adela, > Le 2 sept. 2020 à 13:32, Adela Vais <[email protected]> a écrit : > > * examples/d/calc: Created. > * examples/d/simple: Created.
I have smashed your patches 2 and 3 together, and made a number of changes: - use the imperative in the commit messages - preserve my changes in the tests - in the local.mk, fix the definition of the directory in which the examples will be installed - preserve my changes in local.mk where -o is passed before the argument, not after. - keep just one README, not three Cheers! commit 8032dde38397c05777b45c5f3d41637724c7d599 Author: Adela Vais <[email protected]> Date: Wed Sep 2 14:32:22 2020 +0300 examples: d: duplicate the example as "simple" and "calc" * examples/d/Makefile, examples/d/calc.d, examples/d/calc.test, examples/d/calc/local.mk: Move into... * examples/d/calc, examples/d/simple: these new directories. diff --git a/examples/d/README.md b/examples/d/README.md index fe05ef27..86cb10a8 100644 --- a/examples/d/README.md +++ b/examples/d/README.md @@ -5,9 +5,12 @@ This directory contains examples of Bison grammar files in D. You can run `make` to compile these examples. And `make clean` to tidy afterwards. -## d/calc.y +## d/simple.y The usual calculator. +## d/calc.y +A richer implementation of the calculator. + <!--- Local Variables: diff --git a/examples/d/Makefile b/examples/d/calc/Makefile similarity index 100% rename from examples/d/Makefile rename to examples/d/calc/Makefile diff --git a/examples/d/calc.test b/examples/d/calc/calc.test similarity index 100% rename from examples/d/calc.test rename to examples/d/calc/calc.test diff --git a/examples/d/calc.y b/examples/d/calc/calc.y similarity index 100% rename from examples/d/calc.y rename to examples/d/calc/calc.y diff --git a/examples/d/calc/local.mk b/examples/d/calc/local.mk new file mode 100644 index 00000000..70b045c4 --- /dev/null +++ b/examples/d/calc/local.mk @@ -0,0 +1,36 @@ +## Copyright (C) 2018-2020 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 <http://www.gnu.org/licenses/>. + +calcddir = $(docdir)/%D% + +## ------ ## +## Calc. ## +## ------ ## + +if ENABLE_D + check_SCRIPTS += %D%/calc + TESTS += %D%/calc.test +endif +EXTRA_DIST += %D%/calc.test + +%D%/calc.d: %D%/calc.y $(dependencies) + $(AM_V_GEN)$(MKDIR_P) %D% + $(AM_V_at)$(BISON) -o $@ $(srcdir)/%D%/calc.y + +%D%/calc: %D%/calc.d + $(AM_V_GEN) $(DC) $(DCFLAGS) -of$@ %D%/calc.d + +dist_calcd_DATA = %D%/calc.y %D%/Makefile +CLEANFILES += %D%/calc %D%/calc.[do] diff --git a/examples/d/local.mk b/examples/d/local.mk index 4497e5a3..9a5d1006 100644 --- a/examples/d/local.mk +++ b/examples/d/local.mk @@ -14,23 +14,7 @@ ## along with this program. If not, see <http://www.gnu.org/licenses/>. ddir = $(docdir)/%D% +dist_d_DATA = %D%/README.md -## ------ ## -## Calc. ## -## ------ ## - -if ENABLE_D - check_SCRIPTS += %D%/calc - TESTS += %D%/calc.test -endif -EXTRA_DIST += %D%/calc.test - -%D%/calc.d: %D%/calc.y $(dependencies) - $(AM_V_GEN)$(MKDIR_P) %D% - $(AM_V_at)$(BISON) -o $@ $(srcdir)/%D%/calc.y - -%D%/calc: %D%/calc.d - $(AM_V_GEN) $(DC) $(DCFLAGS) -of$@ %D%/calc.d - -dist_d_DATA = %D%/calc.y %D%/Makefile %D%/README.md -CLEANFILES += %D%/calc %D%/calc.[do] +include %D%/calc/local.mk +include %D%/simple/local.mk diff --git a/examples/d/simple/Makefile b/examples/d/simple/Makefile new file mode 100644 index 00000000..45ae6289 --- /dev/null +++ b/examples/d/simple/Makefile @@ -0,0 +1,25 @@ +# This Makefile is designed to be simple and readable. It does not +# aim at portability. It requires GNU Make. + +BISON = bison +DC = dmd +XSLTPROC = xsltproc + +all: calc + +%.d %.xml %.gv: %.y + $(BISON) $(BISONFLAGS) --xml --graph=$*.gv -o $*.d $< + +%: %.d + $(DC) $(DCFLAGS) $< + +run: calc + @echo "Type arithmetic expressions. Quit with ctrl-d." + ./$< + +html: calc.html +%.html: %.xml + $(XSLTPROC) $(XSLTPROCFLAGS) -o $@ $$($(BISON) --print-datadir)/xslt/xml2xhtml.xsl $< + +clean: + rm -f calc calc.d calc.xml calc.gv calc.html *.o diff --git a/examples/d/simple/calc.test b/examples/d/simple/calc.test new file mode 100644 index 00000000..6b237592 --- /dev/null +++ b/examples/d/simple/calc.test @@ -0,0 +1,36 @@ +#! /bin/sh + +# Copyright (C) 2018-2020 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 <http://www.gnu.org/licenses/>. + +cat >input <<EOF +1 + 2 * 3 +EOF +run 0 7 + +cat >input <<EOF ++1 + +2 * +3 +EOF +run 0 7 + +cat >input <<EOF +-1 + -2 * -3 +EOF +run 0 5 + +cat >input <<EOF +1 + 2 * * 3 +EOF +run 1 "err: syntax error, unexpected *, expecting + or - or ( or number" diff --git a/examples/d/simple/calc.y b/examples/d/simple/calc.y new file mode 100644 index 00000000..15b4f7c7 --- /dev/null +++ b/examples/d/simple/calc.y @@ -0,0 +1,156 @@ +/* Parser and scanner for calc in D. -*- D -*- + + Copyright (C) 2018-2020 Free Software Foundation, Inc. + + This file is part of Bison, the GNU Compiler Compiler. + + 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 <http://www.gnu.org/licenses/>. */ + +%language "D" + +%define api.parser.class {Calc} +%define parse.error verbose + +%union { + int ival; +} + +/* Bison Declarations */ +%token EQ "=" + PLUS "+" + MINUS "-" + STAR "*" + SLASH "/" + LPAR "(" + RPAR ")" + EOL "end of line" +%token <ival> NUM "number" +%type <ival> exp + +%left "-" "+" +%left "*" "/" +%precedence UNARY /* unary operators */ + +/* Grammar follows */ +%% +input: + line +| input line +; + +line: + EOL +| exp EOL { writeln ($exp); } +| error EOL +; + +exp: + NUM { $$ = $1; } +| exp "+" exp { $$ = $1 + $3; } +| exp "-" exp { $$ = $1 - $3; } +| exp "*" exp { $$ = $1 * $3; } +| exp "/" exp { $$ = $1 / $3; } +| "+" exp %prec UNARY { $$ = $2; } +| "-" exp %prec UNARY { $$ = -$2; } +| "(" exp ")" { $$ = $2; } +; + +%% +import std.range.primitives; +import std.stdio; + +auto calcLexer(R)(R range) + if (isInputRange!R && is (ElementType!R : dchar)) +{ + return new CalcLexer!R(range); +} + +auto calcLexer (File f) +{ + import std.algorithm : map, joiner; + import std.utf : byDchar; + + return f.byChunk(1024) // avoid making a syscall roundtrip per char + .map!(chunk => cast(char[]) chunk) // because byChunk returns ubyte[] + .joiner // combine chunks into a single virtual range of char + .calcLexer; // forward to other overload +} + +class CalcLexer(R) : Lexer + if (isInputRange!R && is (ElementType!R : dchar)) +{ + R input; + + this(R r) { input = r; } + + // Should be a local in main, shared with %parse-param. + int exit_status = 0; + + public void yyerror (string s) + { + exit_status = 1; + stderr.writeln (s); + } + + YYSemanticType semanticVal_; + + public final @property YYSemanticType semanticVal () + { + return semanticVal_; + } + + int yylex () + { + import std.uni : isWhite, isNumber; + + // Skip initial spaces + while (!input.empty && input.front != '\n' && isWhite (input.front)) + input.popFront; + + if (input.empty) + return TokenKind.YYEOF; + + // Numbers. + if (input.front.isNumber) + { + import std.conv : parse; + semanticVal_.ival = input.parse!int; + return TokenKind.NUM; + } + + // Individual characters + auto ch = input.front; + input.popFront; + switch (ch) + { + case '=': return TokenKind.EQ; + case '+': return TokenKind.PLUS; + case '-': return TokenKind.MINUS; + case '*': return TokenKind.STAR; + case '/': return TokenKind.SLASH; + case '(': return TokenKind.LPAR; + case ')': return TokenKind.RPAR; + case '\n': return TokenKind.EOL; + default: assert(0); + } + } +} + +int main () +{ + auto l = calcLexer (stdin); + auto p = new Calc (l); + p.parse (); + return l.exit_status; +} diff --git a/examples/d/simple/local.mk b/examples/d/simple/local.mk new file mode 100644 index 00000000..fb99386a --- /dev/null +++ b/examples/d/simple/local.mk @@ -0,0 +1,36 @@ +## Copyright (C) 2018-2020 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 <http://www.gnu.org/licenses/>. + +simpleddir = $(docdir)/%D% + +## ------ ## +## Calc. ## +## ------ ## + +if ENABLE_D + check_SCRIPTS += %D%/calc + TESTS += %D%/calc.test +endif +EXTRA_DIST += %D%/calc.test + +%D%/calc.d: %D%/calc.y $(dependencies) + $(AM_V_GEN)$(MKDIR_P) %D% + $(AM_V_at)$(BISON) -o $@ $(srcdir)/%D%/calc.y + +%D%/calc: %D%/calc.d + $(AM_V_GEN) $(DC) $(DCFLAGS) -of$@ %D%/calc.d + +dist_simpled_DATA = %D%/calc.y %D%/Makefile +CLEANFILES += %D%/calc %D%/calc.[do]
