Commit 74df6f47 authored by Frank B. Brokken's avatar Frank B. Brokken

Imported Upstream version 4.05.00

parent c37b5159
enumsolution
element
atdollar
block atdollar
element
enumsolution
firstset element
followset firstset terminal
generator writer
grammar symbol production
item lookaheadset production
lookaheadset firstset terminal
next enumsolution statetype stateitem symbol item
nonterminal production firstset followset symbol
options
rmshift
parser scanner rules symtab
production block terminal symbol
rmreduction
statetype
scanner block options
firstset element
symbol firstset
terminal symbol
production block terminal
followset terminal
nonterminal production firstset followset
symtab nonterminal
rules nonterminal
grammar rules
lookaheadset rules
rmshift
rrconflict stateitem lookaheadset rrdata
rrdata lookaheadset
item lookaheadset
parser scanner rules symtab
transition item
stateitem item rmshift rmreduction rrdata
rrconflict stateitem
next enumsolution statetype stateitem
rules nonterminal block terminal production symbol
scanner block
srconflict rmreduction next
state srconflict rrconflict lookaheadset
writer next lookaheadset state
generator writer options
state statetype next srconflict rrconflict
stateitem symbol item lookaheadset rmshift rmreduction rrdata
statetype
symbol firstset element
symtab nonterminal symbol terminal
terminal symbol
transition item lookaheadset
writer next
- %nonassoc should probably produce an error when %nonassoc operators are used
repeatedly.
#define VERSION "4.04.01"
#define VERSION "4.05.00"
#define YEARS "2005-2013"
......@@ -34,9 +34,6 @@ namespace
Arg::LongOption("error-verbose"),
{"filenames", 'f'},
Arg::LongOption("flex"),
// options only
Arg::LongOption("force-class-header"),
Arg::LongOption("force-implementation-header"),
{"help", 'h'}, // option only
......@@ -68,6 +65,7 @@ namespace
Arg::LongOption("scanner-debug"),
{"scanner-matched-text-function", Arg::Required},
{"scanner-token-function", Arg::Required},
{"scanner-class-name", Arg::Required},
Arg::LongOption("show-filenames"), // option only
{"skeleton-directory", 'S'}, // option only
......@@ -77,7 +75,7 @@ namespace
Arg::LongOption("thread-safe"), // options only
{"usage", 'h'},
{"verbose", 'V'},
// shows rules, tkoens, final states and kernel items,
// shows rules, tokens, final states and kernel items,
// and describes conflicts when found
{"version", 'v'},
};
......@@ -145,7 +143,6 @@ try
generator.baseClassHeader();
generator.classHeader();
generator.implementationHeader();
generator.parseFunction();
}
catch(exception const &err)
......
This diff is collapsed.
......@@ -6,7 +6,7 @@ void Block::atIndex(size_t lineNr, string const &text)
d_atDollar.push_back(
AtDollar(
AtDollar::AT, length(), lineNr,
text, A2x(text.substr(1)), false
text, stol(text.substr(1)), false
)
);
append(text);
......
......@@ -5,10 +5,6 @@
#include <iterator>
#include <limits>
#include <bobcat/x2a>
#include <bobcat/a2x>
using namespace std;
using namespace FBB;
......@@ -6,7 +6,7 @@ void Block::dollarIndex(size_t lineNr, string const &text, bool member)
{
d_atDollar.push_back(
AtDollar(AtDollar::DOLLAR, length(), lineNr,
text, A2x(text.substr(1)), member)
text, stol(text.substr(1)), member)
);
append(text);
}
......@@ -8,7 +8,7 @@ void Block::IDindex(size_t lineNr, string const &text)
d_atDollar.push_back(
AtDollar(
AtDollar::DOLLAR, length(), lineNr,
text, text.substr(begin, end - begin), A2x(text.substr(end + 1))
text, text.substr(begin, end - begin), stol(text.substr(end + 1))
)
);
......
bisonc++ (4.05.00)
* Added the directive %scanner-class-name specifying the class name of the
scanner to use in combination with the %scanner directive
* re-installed the --namespace option (see the next item)
* Warnings are issued when options or directives are specified wchich are
ignored because the target file (e.g., parser.h, parser.ih) already
exists. These warnings are not issued for parse.cc and parserbase.h, which
are by default rewritten at each bisonc++ run. These warnings are issued
for the `class-header', `class-name', `baseclass-header', `namespace',
`scanner', `scanner-class-name' and `scanner-token-function'
options/directives.
* The --force-class-header and --force-implementation-header options were
removed: 'rm ...' should be used instead.
* man-page and manual updated
* CLASSES class dependencies updated, icmconf's USE_ALL activated
-- Frank B. Brokken <f.b.brokken@rug.nl> Sat, 10 Aug 2013 10:16:17 +0200
bisonc++ (4.04.01)
* Removed the possibility to specify path names for the --baseclass-header,
......
......@@ -244,9 +244,16 @@ file. Directives affecting the class header or implementation header file are
ignored if these files already exist.
Directives accepting a `filename' do not accept path names, i.e., they
cannot contain directory separators (tt(/)); options accepting a 'pathname'
cannot contain directory separators (tt(/)); directives accepting a 'pathname'
may contain directory separators. A 'pathname' using blank characters should
be surrounded by double quotes.
Some directives may generate warnings. This happens when an directive
conflicts with the contents of a file which bic() cannot modify (e.g., a
parser class header file exists, but doesn't define a name space, but a
tt(%namespace) directive was provided). In those cases the directive is
ignored, and hand-editing may then be required to effectuate the directive.
itemization(
it() bf(%baseclass-header) tt(filename) nl()
tt(Filename) defines the name of the file to contain the parser's
......@@ -254,6 +261,10 @@ be surrounded by double quotes.
tokens. Defaults to the name of the parser class plus the suffix
tt(base.h). This directive is overruled by the
bf(--baseclass-header) (bf(-b)) command-line option.
A warning is issued if this directive is used and an already
existing parser class header file does not contain tt(#include
"filename").
it() bf(%baseclass-preinclude) tt(pathname)nl()
tt(Pathname) defines the path to the file preincluded by the
parser's base-class header. See the description of the
......@@ -266,10 +277,19 @@ be surrounded by double quotes.
class. Defaults to the name of the parser class plus the suffix
tt(.h) This directive is overruled by the bf(--class-header)
(bf(-c)) command-line option.
A warning is issued if this directive is used and an already
existing implementation header file does not contain tt(#include
"filename").
it() bf(%class-name) tt(parser-class-name) nl()
Declares the name of the parser class. It defines the name of the
bf(C++) class that is generated. If no tt(%class-name) is
specified the default class name tt(Parser) is used.
A warning is issued if this directive is used and an already
existing parser-class header file does not define tt(class
`className') and/or if an already existing implementation header
file does not define members of the class tt(`className').
it() bf(%debug) nl()
Provide tt(parse) and its support functions with debugging code,
showing the actual parsing process on the standard output
......@@ -295,7 +315,7 @@ be surrounded by double quotes.
tt(Filename) is a generic filename that is used for all header
files generated by bic(). Options defining specific filenames are
also available (which then, in turn, overrule the name specified
by this option). This directive is overruled by the
by this directive). This directive is overruled by the
bf(--filenames) (bf(-f)) command-line option.
it() bf(%flex) nl()
When provided, the scanner member returning the matched text is
......@@ -375,11 +395,15 @@ be surrounded by double quotes.
it() bf(%namespace) tt(namespace) nl()
Define all of the code generated by bic() in the name space
tt(namespace). By default no name space is defined. If this
options is used the implementation header is provided with a
directive is used the implementation header is provided with a
commented out tt(using namespace) declaration for the specified
name space. In addition, the parser and parser base class
header files also use the specified namespace to define their
include guard directives.
A warning is issued if this directive is used and an already
existing parser-class header file and/or implementation header
file does not define tt(namespace identifier).
it() bf(%negative-dollar-indices) nl()
Do not generate warnings when zero- or negative dollar-indices are
used in the grammar's action blocks. Zero or negative
......@@ -454,21 +478,34 @@ be surrounded by double quotes.
used directive defines the tokens having the lowest precedence,
the last used defines the tokens having the highest priority. See
also tt(%token) below.
it() bf(%scanner) tt(header)nl()
Use tt(header) as the pathname to the file pre-included in the
it() bf(%scanner) tt(pathname)nl()
Use tt(pathname) as the path name to the file pre-included in the
parser's class header. See the description of the tt(--scanner)
option for details about this option. Similar to the convention
adopted for this argument, tt(header) by default is surrounded by
double quotes. However, when the argument is surrounded by
pointed brackets tt(#include <header>) is included. This directive
results in the definition of a composed tt(Scanner d_scanner) data
member into the generated parser, and in the definition of a
tt(int lex()) member, returning tt(d_scanner.lex()).
option for details about this directive. Similar to the convention
adopted for this argument, tt(pathname) by default is surrounded
by double quotes. However, when the argument is surrounded by
pointed brackets tt(#include <pathname>) is included. This
directive results in the definition of a composed tt(Scanner
d_scanner) data member into the generated parser, and in the
definition of a tt(int lex()) member, returning
tt(d_scanner.lex()).
By specifying the tt(%flex) directive the function
tt(d_scanner.yylex()) is called. Any other function to call can be
specified using the tt(--scanner-token-function) option (or
tt(%scanner-token-function) directive).
A warning is issued if this directive is used and an already
existing parser class header file does not include tt(`pathname').
it() bf(%scanner-class-name) tt(scannerClassName) nl()
Defines the name of the scanner class, declared by the tt(pathname)
header file that is specified at the tt(scanner) option or
directive. By default the class name tt(Scanner) is used.
A warning is issued if this directive is used and either the
tt(scanner) directive was not provided, or the parser class
interface in an already existing parser class header file does not
declare a scanner class tt(d_scanner) object.
it() bf(%scanner-matched-text-function) tt(function-call) nl()
The scanner function returning the text that was matched by the
lexical scanner after its token function (see below) has
......@@ -492,6 +529,10 @@ be surrounded by double quotes.
)
If the function call contains white space
tt(scanner-token-function) should be surrounded by double quotes.
A warning is issued if this directive is used and the scanner token
function is not called from the code in an already
existing implementation header.
it() bf(%start) tt(non-terminal) nl()
The non-terminal tt(non-terminal) should be used as the grammar's
start-symbol. If omitted, the first grammatical rule is used
......
../manual/invoking/options.yo
\ No newline at end of file
......@@ -7,3 +7,7 @@
tt(--dont-rewrite-baseclass-header) options. This directive is
overruled by the bf(--baseclass-header) (bf(-b)) command-line
option.
A warning is issued if this directive is used and an already
existing parser class header file does not contain tt(#include
"filename").
......@@ -3,3 +3,8 @@
class. Defaults to the name of the parser class plus the suffix
tt(.h) This directive is overruled by the bf(--class-header)
(bf(-c)) command-line option.
A warning is issued if this directive is used and an already
existing parser-class header file does not define tt(class
`className') and/or if an already existing implementation header
file does not define members of the class tt(`className').
......@@ -42,6 +42,12 @@ contain directory separators.
Sometimes directives have analogous command-line options. In those cases
command-line options take priority over directives.
Some directives may generate warnings. This happens when an directive
conflicts with the contents of a file which bic() cannot modify (e.g., a
parser class header file exists, but doesn't define a name space, but a
tt(%namespace) directive was provided). In those cases the directive is
ignored, and hand-editing may then be required to effectuate the directive.
Syntax: bf(%namespace) tt(namespace) nl()
Defines the parser class in the namespace tt(namespace). By default no
namespace is defined.
Defines all of the code generated by bic() in the namespace
tt(namespace). By default no namespace is defined.
If this options is used the implementation header will contain a commented
out tt(using namespace) directive for the requested namespace.
......@@ -8,3 +8,6 @@ out tt(using namespace) directive for the requested namespace.
In addition, the parser and parser base class header files also use the
specified namespace to define their include guard directives.
A warning is issued if this directive is used and an already existing
parser-class header file and/or implementation header file does not define
tt(namespace identifier).
......@@ -11,3 +11,8 @@ Bison++.
it() Contrary to Bison++'s bf(%name) directive, bf(%class-name) may
appear anywhere in the directive section of the grammar specification file.
)
A warning is issued if this directive is used and an already existing
parser-class header file does not define tt(class `className') and/or if an
already existing implementation header file does not define members of the
class tt(`className').
bf(%scanner) tt(header)nl()
Syntax: bf(%scanner) tt(header)nl()
Use tt(header) as the pathname of a file to include in the parser's class
header. See the description of the link(--scanner)(SCANOPT) option for details
about this option. This directive also implies the automatic definition of a
......@@ -12,3 +12,6 @@ The specfied tt(header) file will be surrounded by double quotes if no
delimiters were provided. If pointed brackets (tt(<...>)) are used, they are
kept.
A warning is issued if this directive is used and an already existing parser
class header file does not include tt(`pathname').
Syntax: bf(%scanner-class-name) tt(scannerClassName) nl()
Defines the name of the scanner class, declared by the tt(pathname)
header file that is specified at the tt(scanner) option or
directive. By default the class name ttt(Scanner) is used.
A warning is issued if this directive is used and either the
tt(scanner) directive was not provided, or the parser class
interface in an already existing parser class header file does not
declare a scanner class tt(d_scanner) object.
......@@ -10,3 +10,6 @@ Syntax: bf(%scanner-token-function) tt(function-call) nl()
If the function call contains white space
tt(scanner-token-function) should be surrounded by double quotes.
A warning is issued if this directive is used and the scanner token
function is not called from the code in an already
existing implementation header.
......@@ -5,6 +5,30 @@ affecting the class header or implementation header file are ignored if these
files already exist. Options accepting a `filename' do not accept path names,
i.e., they cannot contain directory separators (tt(/)); options accepting a
'pathname' may contain directory separators.
Some options may generate warnings. This happens when an option conflicts with
the contents of a file which bic() cannot modify (e.g., a parser
class header file exists, but doesn't define a name space, but a
tt(--namespace) option was provided). In those cases the option is
ignored, and hand-editing may then be required to effectuate the option.
COMMENT(
class header: warn for class-name mismatch
warn for not including baseclass-header
warn for namespace mismatch
if the 'scanner' option was provided:
warn for missing "scanner" include-spec
warn for missing Scanner d_scanner spec.
implementation header: warn for class-name mismatch
(in inline defined members)
warn for not including the class header
warn for namespace mismatch
warn for a mismatch in the scanner-token-function
name
END)
itemization(
it() loption(analyze-only) (soption(A))nl()
Only analyze the grammar. No files are (re)written. This option can
......@@ -21,6 +45,10 @@ i.e., they cannot contain directory separators (tt(/)); options accepting a
tt(--no-baseclass-header) and tt(--dont-rewrite-baseclass-header)
below).
A warning is issued if this option is used and an already
existing parser class header file does not contain tt(#include
"filename").
it() label(PREINCLUDE) lsoption(baseclass-preinclude)(H)(pathname)nl()
tt(Pathname) defines the path to the file preincluded in the
parser's base-class header. This option is needed in situations
......@@ -48,11 +76,20 @@ i.e., they cannot contain directory separators (tt(/)); options accepting a
class. Defaults to the name of the parser class plus the suffix
tt(.h)
A warning is issued if this option is used and an already
existing implementation header file does not contain tt(#include
"filename").
it() loption(class-name) tt(className) nl()
Defines the name of the bf(C++) class that is generated. If
neither this option, nor the tt(%class-name) directory is
specified, then the default class name (tt(Parser)) is used.
A warning is issued if this option is used and an already
existing parser-class header file does not define tt(class
`className') and/or if an already existing implementation header
file does not define members of the class tt(`className').
it() lsoption(class-skeleton)(C)(pathname)nl()
tt(Pathname) defines the path name to the file containing the
skeleton of the parser class. It defaults to the
......@@ -97,16 +134,6 @@ i.e., they cannot contain directory separators (tt(/)); options accepting a
bf(flexc++)(1) is used. This option is only interpreted if the
tt(--scanner) option or tt(%scanner) directive is also used.
it() loption(force-class-header)nl()
By default the generated class header is not overwritten once it
has been created. This option can be used to force the
(re)writing of the file containing the parser's class.
it() loption(force-implementation-header)nl()
By default the generated implementation header is not overwritten
once it has been created. This option can be used to force the
(re)writing of the implementation header file.
it() loption(help) (soption(h))nl()
Write basic usage information to the standard output stream and
terminate.
......@@ -114,7 +141,8 @@ i.e., they cannot contain directory separators (tt(/)); options accepting a
it() lsoption(implementation-header)(i)(filename)nl()
tt(Filename) defines the name of the file to contain the
implementation header. It defaults to the name of the generated
parser class plus the suffix tt(.ih). nl()
parser class plus the suffix tt(.ih).
The implementation header should contain all directives and
declarations em(only) used by the implementations of the parser's
member functions. It is the only header file that is included by
......@@ -141,6 +169,19 @@ i.e., they cannot contain directory separators (tt(/)); options accepting a
it() label(MAXDEPTH) laoption(max-inclusion-depth)(value)nl()
Set the maximum number of nested grammar files. Defaults to 10.
it() loption(namespace) tt(identifier) nl()
Define all of the code generated by bic() in the name space
tt(identifier). By default no name space is defined. If this
options is used the implementation header is provided with a
commented out tt(using namespace) declaration for the specified
name space. In addition, the parser and parser base class
header files also use the specified namespace to define their
include guard directives.
A warning is issued if this option is used and an already existing
parser-class header file and/or implementation header file does
not define tt(namespace identifier).
it() loption(no-baseclass-header)nl()
Do not write the file containing the parser class' base class, even
if that file doesn't yet exist. By default the file containing the
......@@ -236,17 +277,30 @@ i.e., they cannot contain directory separators (tt(/)); options accepting a
return d_scanner.lex();
}
)
and an object tt(Scanner d_scanner) is composed into the
parser. The example shows the function that's called by
default. When the tt(--flex) option (or tt(%flex) directive) is
specified the function tt(d_scanner.yylex()) is called. Any other
function to call can be specified using the
tt(--scanner-token-function) option (or
and an object tt(Scanner d_scanner) is composed into the parser
(but see also option tt(scanner-class-name)). The example shows
the function that's called by default. When the tt(--flex) option
(or tt(%flex) directive) is specified the function
tt(d_scanner.yylex()) is called. Any other function to call can be
specified using the tt(--scanner-token-function) option (or
tt(%scanner-token-function) directive).
By default tt(header) is surrounded by double quotes (using, e.g.,
tt(#include "header")). When the argument is surrounded by
pointed brackets tt(#include <header>) is included.
By default bic() surrounds tt(pathname) by double quotes (using,
e.g., tt(#include "pathname")). When tt(pathname) is surrounded
by pointed brackets tt(#include <pathname>) is included.
A warning is issued if this option is used and an already existing
parser class header file does not include tt(`pathname').
it() loption(scanner-class-name) tt(scannerClassName) nl()
Defines the name of the scanner class, declared by the tt(pathname)
header file that is specified at the tt(scanner) option or
directive. By default the class name tt(Scanner) is used.
A warning is issued if this option is used and either the
tt(scanner) option was not provided, or the parser class interface
in an already existing parser class header file does not declare a
scanner class tt(d_scanner) object.
it() loption(scanner-debug)nl()
Show de scanner's matched rules and returned tokens. This offers an
......@@ -279,6 +333,10 @@ i.e., they cannot contain directory separators (tt(/)); options accepting a
--scanner-token-function "myScanner.nextToken()"
)
A warning is issued if this option is used and the scanner token
function is not called from the code in an already
existing implementation header.
it() loption(show-filenames)nl()
Writes the names of the generated files to the standard error
stream.
......@@ -291,8 +349,7 @@ i.e., they cannot contain directory separators (tt(/)); options accepting a
it() laoption(target-directory)(pathname) nl()
tt(Pathname) defines the directory where generated files should be
written. By default this is the directory where bic() is
called. This directive is overruled by the tt(--target-directory)
command-line option.
called.
it() loption(thread-safe)nl()
No static data are modified, making bic() thread-safe.
......@@ -312,4 +369,5 @@ i.e., they cannot contain directory separators (tt(/)); options accepting a
it() loption(version) (soption(v))nl()
Display bic()'s version number and terminate.
)
......@@ -3,18 +3,48 @@
// New members and other facilites may be added to the parser's class header
// after its initial generation.
// Writing a base class header may be forced by the --force-class-header
// option. Otherwise, it's not rewritten by bisonc++ once it's available
// A class header is not rewritten by bisonc++ once it's available
void Generator::classHeader() const
{
if
(
not d_arg.option(0, "force-class-header")
&&
d_stat.set(d_options.classHeader())
)
string const &classHeader = d_options.classHeader();
if (d_stat.set(classHeader))
{
// class-name must match
warnExisting(classHeader, "class-name", d_options.className(),
"^class " + d_options.className() + "\\b");
warnExisting(classHeader, "baseclass-header",
d_options.baseclassHeaderName(),
"^#include \"" + d_options.baseclassHeaderName() + '"');
// if a namespace was provided: it must be present
if (not d_options.nameSpace().empty())
warnExisting(classHeader, "namespace", d_options.nameSpace(),
"^namespace " + d_options.nameSpace() + "\\b");
if (d_options.specified("scanner"))
{
// the 'scanner' include spec. must be present
warnExisting(classHeader, "scanner", d_options.scannerInclude(),
"^#include " + d_options.scannerInclude());
// the 'scanner-class-name must be present
if (d_options.specified("scanner-class-name"))
warnExisting(classHeader, "scanner-class-name",
d_options.scannerClassName(),
"^[[:space:]]*" +
d_options.scannerClassName() +
" d_scanner;");
}
else if (d_options.specified("scanner-class-name"))
wmsg << '`' << classHeader <<
"': option/directive `scanner-class-name' ignored: "
" option `scanner' not specified" << endl;
return;
}
ofstream out;
ifstream in;
......
......@@ -74,6 +74,15 @@ class Generator
void key(std::ostream &out) const; // show which $insert is
// called, just before the
// generated code
void warnExisting(std::string const &fileName,
std::string const &option,
std::string const &expectedOptionValue,
std::string const &regex) const;
bool grep(std::string const &fileName, std::string const &regex)
const;
void actionCases(std::ostream &out) const;
void baseClass(std::ostream &out) const;
void classH(std::ostream &out) const;
......@@ -111,6 +120,8 @@ class Generator
static void selectSymbolic(Terminal const *terminal,
Terminal::ConstVector &symbolicTokens);
static void replace(std::string &str, char ch,
std::string const &replacement);
};
#endif
......@@ -7,12 +7,18 @@
#include <bobcat/exception>
#include <bobcat/datetime>
#include <bobcat/mstream>
#include <bobcat/pattern>
#include "../options/options.h"
#include "../rules/rules.h"
#include "../terminal/terminal.h"
#include "../production/production.h"
namespace Global
{
void plainWarnings();
}
extern char version[];
using namespace std;
......
......@@ -16,4 +16,6 @@ Generator::Generator(Rules const &rules,
d_polymorphic(polymorphic),
d_writer(d_baseClassScope, rules)
{}
{
Global::plainWarnings();
}
#include "generator.ih"
bool Generator::grep(string const &fileName, string const &regex) const
{
ifstream in(fileName);
Pattern pattern(regex);
string line;
while (getline(in, line))
{
if (pattern << line)
return true;
}
return false;
}
......@@ -5,19 +5,37 @@
// required preprocessor actions for the compilation of the Parser's class
// members
// Writing an implementation header header may be forced by the
// --force-implementation-header option. Otherwise, it's not rewritten by
// The implementation header header is not rewritten by
// bisonc++ once it's available
void Generator::implementationHeader() const
{
if
(
not d_arg.option(0, "force-implementation-header")
&&
d_stat.set(d_options.implementationHeader())
)
string const &implementationHeader = d_options.implementationHeader();
if (d_stat.set(implementationHeader))
{
warnExisting(implementationHeader, "class-header",
d_options.classHeader(),
"^#include \"" + d_options.classHeader() + '"');
warnExisting(implementationHeader, "class-name",
d_options.className(),
"\\b" + d_options.className() + "::");
if (not d_options.nameSpace().empty())
warnExisting(implementationHeader,
"namespace", d_options.nameSpace(),
"^namespace " + d_options.nameSpace() + "\\b");
string pattern = "\\b" + d_options.scannerTokenFunction() + "\\b";
replace(pattern, '(', "\\(");
replace(pattern, ')', "\\)");
warnExisting(implementationHeader, "scanner-token-function",
d_options.scannerTokenFunction(),
pattern);
return;
}
ofstream out;
ifstream in;
......
#include "generator.ih"
void Generator::replace(string &str, char ch, string const &replacement)