[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
FYI: examples/calc++/
From: |
Akim Demaille |
Subject: |
FYI: examples/calc++/ |
Date: |
Wed, 22 Jun 2005 15:36:49 -0000 |
User-agent: |
Gnus/5.1007 (Gnus v5.10.7) Emacs/21.4 (gnu/linux) |
I installed this. In the future, I will have this example be
installed at make install into docdir. A better Makefile etc. will
also come.
2005-06-22 Akim Demaille <address@hidden>
Start a set of simple examples.
* examples/calc++/Makefile, examples/calc++/calc++-driver.cc,
* examples/calc++/calc++-driver.hh,
* examples/calc++/calc++-parser.yy,
* examples/calc++/calc++-scanner.ll, examples/calc++/calc++.cc,
* examples/calc++/compile, examples/calc++/test: New.
Index: examples/calc++/Makefile
===================================================================
RCS file: examples/calc++/Makefile
diff -N examples/calc++/Makefile
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ examples/calc++/Makefile 22 Jun 2005 15:30:34 -0000
@@ -0,0 +1,15 @@
+all: calc++
+
+calc++:
+ flex -ocalc++-scanner.cc calc++-scanner.ll
+ bison -o calc++-parser.cc calc++-parser.yy
+ $(CC) -o calc++ calc++.cc calc++-driver.cc calc++-parser.cc
calc++-scanner.cc
+
+check: all
+ ./test
+
+clean:
+ rm -f *~ *.o *.tab.* input position.hh location.hh stack.hh \
+ calc++-parser.cc calc++-parser.hh \
+ calc++-scanner.cc \
+ calc++
Index: examples/calc++/calc++-driver.cc
===================================================================
RCS file: examples/calc++/calc++-driver.cc
diff -N examples/calc++/calc++-driver.cc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ examples/calc++/calc++-driver.cc 22 Jun 2005 15:30:34 -0000
@@ -0,0 +1,37 @@
+#include "calc++-driver.hh"
+#include "calc++-parser.hh"
+
+calcxx_driver::calcxx_driver ()
+ : trace_scanning (false),
+ trace_parsing (false)
+{
+ variables["one"] = 1;
+ variables["two"] = 2;
+}
+
+calcxx_driver::~calcxx_driver ()
+{
+}
+
+void
+calcxx_driver::parse (const std::string &f)
+{
+ file = f;
+ scan_begin ();
+ yy::calcxx_parser parser (*this);
+ parser.set_debug_level (trace_parsing);
+ parser.parse ();
+ scan_end ();
+}
+
+void
+calcxx_driver::error (const yy::location& l, const std::string& m)
+{
+ std::cerr << l << ": " << m << std::endl;
+}
+
+void
+calcxx_driver::error (const std::string& m)
+{
+ std::cerr << m << std::endl;
+}
Index: examples/calc++/calc++-driver.hh
===================================================================
RCS file: examples/calc++/calc++-driver.hh
diff -N examples/calc++/calc++-driver.hh
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ examples/calc++/calc++-driver.hh 22 Jun 2005 15:30:34 -0000
@@ -0,0 +1,64 @@
+#ifndef CALCXX_DRIVER_HH
+# define CALCXX_DRIVER_HH
+# include <string>
+# include <map>
+
+/// Forward declarations.
+union YYSTYPE;
+
+namespace yy
+{
+ class calcxx_parser;
+ class location;
+}
+
+class calcxx_driver;
+
+// Announce to Flex the prototype we want for lexing function, ...
+# define YY_DECL \
+ int yylex (YYSTYPE* yylval, yy::location* yylloc, calcxx_driver& driver)
+// ... and declare it for the parser's sake.
+YY_DECL;
+
+/// Conducting the whole scanning and parsing of Calc++.
+class calcxx_driver
+{
+public:
+ calcxx_driver ();
+ virtual ~calcxx_driver ();
+
+ /// The variables.
+ std::map<std::string, int> variables;
+
+ /// \name Handling the scanner.
+ /// \{
+ /// Open \a file for scanning.
+ void scan_begin ();
+ /// End scanning, clean up memory.
+ void scan_end ();
+ /// Whether to enable scanner traces.
+ bool trace_scanning;
+ /// \}
+
+ /// \name Handling the parser.
+ /// \{
+ /// Parse the file \a f.
+ void parse (const std::string& f);
+ /// The file being parsed.
+ std::string file;
+ /// Whether to enable parsing traces.
+ bool trace_parsing;
+ /// \}
+
+ /// The result.
+ int result;
+
+ /// \name Error handling.
+ /// \{
+ /// Register a located error.
+ void error (const yy::location& l, const std::string& m);
+ /// Register an error.
+ void error (const std::string& m);
+ /// \}
+};
+#endif
Index: examples/calc++/calc++-parser.yy
===================================================================
RCS file: examples/calc++/calc++-parser.yy
diff -N examples/calc++/calc++-parser.yy
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ examples/calc++/calc++-parser.yy 22 Jun 2005 15:30:34 -0000
@@ -0,0 +1,68 @@
+%skeleton "lalr1.cc" /* -*- C++ -*- */
+%define "parser_class_name" "calcxx_parser"
+%defines
+%{
+# include <string>
+# include "calc++-driver.hh"
+%}
+
+%error-verbose
+
+// The parsing context.
+%parse-param { calcxx_driver& driver }
+%lex-param { calcxx_driver& driver }
+
+%locations
+%initial-action
+{
+ // Initialize the initial location.
+ @$.begin.filename = @$.end.filename = &driver.file;
+};
+
+// Define yydebug.
+%debug
+
+// Symbols.
+
+%union
+{
+ /// Value of a numeric literal.
+ int ival;
+ /// Name of a variable.
+ std::string *sval;
+};
+
+%token YYEOF 0 "end of file"
+%token TOKEN_ASSIGN ":="
+%token <sval> TOKEN_IDENTIFIER "identifier"
+%token <ival> TOKEN_NUMBER "number"
+%type <ival> exp "expression"
+
+%printer { debug_stream () << *$$; } "identifier"
+%destructor { delete $$; } "identifier"
+
+%printer { debug_stream () << $$; } "number" "expression"
+
+%%
+%start unit;
+unit: assignments exp { driver.result = $2; };
+
+assignments: assignments assignment {}
+ | /* Nothing. */ {};
+
+assignment: TOKEN_IDENTIFIER ":=" exp { driver.variables[*$1] = $3; };
+
+%left '+' '-';
+%left '*' '/';
+exp: exp '+' exp { $$ = $1 + $3; }
+ | exp '-' exp { $$ = $1 - $3; }
+ | exp '*' exp { $$ = $1 * $3; }
+ | exp '/' exp { $$ = $1 / $3; }
+ | TOKEN_IDENTIFIER { $$ = driver.variables[*$1]; }
+ | TOKEN_NUMBER { $$ = $1; };
+%%
+void
+yy::calcxx_parser::error (const location& l, const std::string& m)
+{
+ driver.error (l, m);
+}
Index: examples/calc++/calc++-scanner.ll
===================================================================
RCS file: examples/calc++/calc++-scanner.ll
diff -N examples/calc++/calc++-scanner.ll
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ examples/calc++/calc++-scanner.ll 22 Jun 2005 15:30:34 -0000
@@ -0,0 +1,45 @@
+%{ /* -*- C++ -*- */
+
+# include <string>
+# include <cerrno>
+# include "calc++-driver.hh"
+# include "calc++-parser.hh"
+%}
+
+%option noyywrap nounput debug batch
+
+id [a-zA-Z][a-zA-Z_0-9]*
+int [0-9]+
+blank [ \t]
+
+%%
+
+%{
+# define YY_USER_ACTION yylloc->columns (yyleng);
+ yylloc->step ();
+%}
+{blank}+ yylloc->step ();
+[\n]+ yylloc->lines (yyleng); yylloc->step ();
+
+
+[-+*/] return yytext[0];
+":=" return TOKEN_ASSIGN;
+{int} yylval->ival = atoi (yytext); return TOKEN_NUMBER;
+{id} yylval->sval = new std::string (yytext); return TOKEN_IDENTIFIER;
+. driver.error (*yylloc, "invalid character");
+
+%%
+
+void
+calcxx_driver::scan_begin ()
+{
+ yy_flex_debug = trace_scanning;
+ if (!(yyin = fopen (file.c_str (), "r")))
+ error (std::string ("cannot open ") + file);
+}
+
+void
+calcxx_driver::scan_end ()
+{
+ fclose (yyin);
+}
Index: examples/calc++/calc++.cc
===================================================================
RCS file: examples/calc++/calc++.cc
diff -N examples/calc++/calc++.cc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ examples/calc++/calc++.cc 22 Jun 2005 15:30:34 -0000
@@ -0,0 +1,18 @@
+#include <iostream>
+#include "calc++-driver.hh"
+
+int
+main (int argc, const char* argv[])
+{
+ calcxx_driver driver;
+ for (++argv; argv[0]; ++argv)
+ if (*argv == std::string ("-p"))
+ driver.trace_parsing = true;
+ else if (*argv == std::string ("-s"))
+ driver.trace_scanning = true;
+ else
+ {
+ driver.parse (*argv);
+ std::cout << driver.result << std::endl;
+ }
+}
Index: examples/calc++/compile
===================================================================
RCS file: examples/calc++/compile
diff -N examples/calc++/compile
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ examples/calc++/compile 22 Jun 2005 15:30:34 -0000
@@ -0,0 +1,9 @@
+#! /bin/sh
+
+set -ex
+BISON_PKGDATADIR=$HOME/src/bison/data
+export BISON_PKGDATADIR
+
+flex -ocalc++-scanner.cc calc++-scanner.ll
+bison -o calc++-parser.cc calc++-parser.yy
+g++ -o calc++ calc++.cc calc++-driver.cc calc++-parser.cc calc++-scanner.cc
Index: examples/calc++/test
===================================================================
RCS file: examples/calc++/test
diff -N examples/calc++/test
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ examples/calc++/test 22 Jun 2005 15:30:34 -0000
@@ -0,0 +1,26 @@
+#! /bin/sh
+set +e
+cat >input <<EOF
+a := 1
+b := 2
+c := 3
+d := a + b * c
+d
+EOF
+
+./calc++ input
+./calc++ -p input
+
+cat >input <<EOF
+a := 1
+d := a + b * c
+EOF
+./calc++ input
+
+set -x
+echo toto
+cat >input <<EOF
+toto := 1
+toto
+EOF
+./calc++ -s input
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- FYI: examples/calc++/,
Akim Demaille <=