Skip to content

Commit 1520849

Browse files
author
Hirose
committed
Updated README.md
1 parent 13b5b8c commit 1520849

File tree

1 file changed

+45
-13
lines changed

1 file changed

+45
-13
lines changed

README.md

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ If you need a Go language version, please see [*go-peg*](https://github.com/yhir
2323
How to use
2424
----------
2525

26-
This is a simple calculator sample. It shows how to define grammar, associate samantic actions to the grammar and handle semantic values.
26+
This is a simple calculator sample. It shows how to define grammar, associate samantic actions to the grammar, and handle semantic values.
2727

2828
```cpp
2929
// (1) Include the header file
@@ -46,7 +46,7 @@ int main(void) {
4646

4747
parser parser(syntax);
4848

49-
// (3) Setup an action
49+
// (3) Setup actions
5050
parser["Additive"] = [](const SemanticValues& sv) {
5151
switch (sv.choice()) {
5252
case 0: // "Multitive '+' Additive"
@@ -79,14 +79,27 @@ int main(void) {
7979
}
8080
```
8181
82-
Here are available actions:
82+
There are two semantic actions available:
8383
8484
```cpp
8585
[](const SemanticValues& sv, any& dt)
8686
[](const SemanticValues& sv)
8787
```
8888

89-
`const SemanticValues& sv` contains semantic values. `SemanticValues` structure is defined as follows.
89+
`const SemanticValues& sv` contains the following information:
90+
91+
- Semantic values
92+
- Matched string information
93+
- Token information if the rule is literal or uses a token boundary operator
94+
- Choice number when the rule is 'prioritized choise'
95+
96+
`any& dt` is a 'read-write' context data which can be used for whatever purposes. The initial context data is set in `peg::parser::parse` method.
97+
98+
`peg::any` is a simpler implementatin of [boost::any](http://www.boost.org/doc/libs/1_57_0/doc/html/any.html). It can wrap arbitrary data type.
99+
100+
A semantic action can return a value of arbitrary data type, which will be wrapped by `peg::any`. If a user returns nothing in a semantic action, the first semantic value in the `const SemanticValues& sv` argument will be returned. (Yacc parser has the same behavior.)
101+
102+
Here shows the `SemanticValues` structure:
90103

91104
```cpp
92105
struct SemanticValues : protected std::vector<any>
@@ -113,11 +126,7 @@ struct SemanticValues : protected std::vector<any>
113126
}
114127
```
115128
116-
`peg::any` class is very similar to [boost::any](http://www.boost.org/doc/libs/1_57_0/doc/html/any.html). You can obtain a value by castning it to the actual type. In order to determine the actual type, you have to check the return value type of the child action for the semantic value.
117-
118-
`any& dt` is a data object which can be used by the user for whatever purposes.
119-
120-
The following example uses `<` ... ` >` operators. They are the *token boundary* operators.
129+
The following example uses `<` ... ` >` operator, which is *token boundary* operator.
121130
122131
```cpp
123132
auto syntax = R"(
@@ -128,7 +137,7 @@ auto syntax = R"(
128137
129138
peg pg(syntax);
130139
131-
pg["TOKEN"] = [](const SemanticValues& sv) {
140+
pg["TOKEN"] = [](const auto& sv) {
132141
// 'token' doesn't include trailing whitespaces
133142
auto token = sv.token();
134143
};
@@ -145,7 +154,7 @@ peg::pegparser parser(
145154
" ~_ <- [ \t]* "
146155
);
147156

148-
parser["ROOT"] = [&](const SemanticValues& sv) {
157+
parser["ROOT"] = [&](const auto& sv) {
149158
assert(sv.size() == 2); // should be 2 instead of 5.
150159
};
151160

@@ -167,7 +176,7 @@ peg::parser parser(
167176
```cpp
168177
peg::parser parser("NUMBER <- [0-9]+");
169178

170-
parser["NUMBER"] = [](const SemanticValues& sv) {
179+
parser["NUMBER"] = [](const auto& sv) {
171180
auto val = stol(sv.str(), nullptr, 10);
172181
if (val != 100) {
173182
throw peg::parse_error("value error!!");
@@ -191,7 +200,7 @@ parser["RULE"].enter = [](any& dt) {
191200
std::cout << "enter" << std::endl;
192201
};
193202
194-
parser["RULE"] = [](const SemanticValues& sv, any& dt) {
203+
parser["RULE"] = [](const auto& sv, any& dt) {
195204
std::cout << "action!" << std::endl;
196205
};
197206
@@ -230,6 +239,29 @@ PHRASE <- < '"' (!'"' .)* '"' >
230239
%whitespace <- [ \t\r\n]*
231240
```
232241

242+
AST generation
243+
--------------
244+
245+
*cpp-peglib* is able to generate an AST (Abstract Syntax Tree) when parsing. `enable_ast` method on `peg::parser` class enables the feature.
246+
247+
```
248+
peg::parser parser("...");
249+
250+
parser.enable_ast();
251+
252+
shared_ptr<peg::Ast> ast;
253+
if (parser.parse("...", ast)) {
254+
cout << peg::ast_to_s(ast);
255+
256+
ast = peg::AstOptimizer(true).optimize(ast);
257+
cout << peg::ast_to_s(ast);
258+
}
259+
```
260+
261+
`peg::AstOptimizer` removes redundant nodes to make a AST simpler. You can make your own AST optimizers to fit your needs.
262+
263+
See actual usages in the [AST calculator example](https://github.com/yhirose/cpp-peglib/blob/master/example/calc3.cc) and [PL/0 Interpreter example](https://github.com/yhirose/cpp-peglib/blob/master/language/pl0/pl0.cc).
264+
233265
Simple interface
234266
----------------
235267

0 commit comments

Comments
 (0)