Motivation

My purpose was creation of my original language, so I tried many parser generator, but there were no satisfactory program for following reasons:

bison / byacc:
Too old design. That interferes other codes. The license was also bad.
D parser:
I had used it but there was a problem in data presentation. Too difficult to use in VC.
Elkhound:
Hard to use (very few samples).
spirit:
Hard to debug.
Others:
Similar to yacc.

By introducing reusability raised by modern programming, it can make parser generators used widely, but the existing parser generaters didn't escape from old design, and they are difficult to use. So I did reinvent wheels. I removed inconvenient points as possible.

Caper is basically and simply based on the algorithm of the dragon book (partially "Modern Compiler Implementation in Ml"). Don't expect academical freshness.

The Description of Source Files

grammar.hpp
--- interface classes for dynamic grammar definition
lr.hpp
--- the common part of dynamic LR-system analysis engine
fastlalr.hpp
--- dynamic LALR(1) analysis engline, create table and parser from grammar of grammar.hpp
^^^ This 3 files are dynamic parser engine.

caper_ast.hpp
--- The definition of AST of Caper input grammar file (.cpg)
caper.cpp
--- The body
caper_cpg.cpp
make_cpg_parser
--- ....caper input grammar file (.cpg) The parser generation routine
<The example of dynamic parser engine>
collect_informations
--- Collection of declarations and type definitions from AST
caper_tgt.cpp
make_target_parser
--- The routine that creates target sentence analysis table from input grammar
caper_generate_cpp.cpp
--- C++ generator
caper_generate_js.cpp
--- JavaScript generator

About Exception-Safety

Caper doesn't generate any exceptions.

However, the template paramaters "Value" and "SemanticAction" requires consideration.

SemanticAction is safely and effectively implemented. Thus, you can raise exceptions in SemanticAction freely. If SemanticAction was stopped by exception, then the call of post that started the SemanticAction up, will be stopped, the internal status (stack) of parser will be also rollbacked to the moment just before the call of post. So to say, it's a "strong guarantee".

On other hand, I have no good idea to realize "strong guarantee" without high cost about treatment of stack including process of Value (I have imagined backup of the whole stack only).

In practical use, problems will be occured if template parameter "Value" causes

There is no problem if your application doesn't throw these exceptions. For example, no problem if Value was int or just a pointer.

If Value was generated exceptions in above member function, the status of parser will be indefinite, and the result of the followed post will be also indefinite (acceess exception may be caused). If it became indefinite, you can resume by doing reset, but the status of parser will return to the initial status. Even if the status of parser became indefinite, there is no resource leaks, so you can destroy it safely. You can destroy even if indefinite.

If you want to save the status of parser (it may take time), you may create another parser instance by using copy constructor. Above "stack copy is high burden" was mensioned about the general worst conditions, I don't think the stack of LALR parser will be deep practically (depends on grammar and data).

In addition, if caper uses std::vector for stack, std::vector can cause exceptions in memory allocation. In this case, the parser will treat it properly as the case of SemanticAction. An option makes STL unused, then exceptions won't be caused, but stack size will be limited.

Well, currently, some bugs might be still contained...