* spelling: bracket

Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>

* spelling: build

Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>

* spelling: commandline

Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>

* spelling: debugging

Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>

* spelling: definition

Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>

* spelling: editing

Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>

* spelling: editors

Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>

* spelling: github

Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>

* spelling: grammar

Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>

* spelling: multiplicative

Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>

* spelling: optimization

Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>

* spelling: optimize

Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>

* spelling: semicolon

Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>

* spelling: whitespace

Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>

---------

Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
pull/295/head
Josh Soref 4 months ago committed by GitHub
parent bd0e43e550
commit 65ccaaa7c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      .github/workflows/cmake.yml
  2. 68
      README.md
  3. 14
      docs/index.js
  4. 14
      example/calc.cc
  5. 10
      grammar/cpp-peglib.peg
  6. 42
      lint/README.md
  7. 18
      peglib.h
  8. 20
      test/test1.cc
  9. 4
      test/test2.cc

@ -32,7 +32,7 @@ jobs:
working-directory: ${{runner.workspace}}/build
# Note the current convention is to use the -S and -B options here to specify source
# and build directories, but this is only available with CMake 3.13 and higher.
# The CMake binaries on the Github Actions machines are (as of this writing) 3.12
# The CMake binaries on the GitHub Actions machines are (as of this writing) 3.12
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE
- name: Build

@ -2,7 +2,7 @@ cpp-peglib
==========
[![](https://github.com/yhirose/cpp-peglib/workflows/CMake/badge.svg)](https://github.com/yhirose/cpp-peglib/actions)
[![Bulid Status](https://ci.appveyor.com/api/projects/status/github/yhirose/cpp-peglib?branch=master&svg=true)](https://ci.appveyor.com/project/yhirose/cpp-peglib)
[![Build Status](https://ci.appveyor.com/api/projects/status/github/yhirose/cpp-peglib?branch=master&svg=true)](https://ci.appveyor.com/project/yhirose/cpp-peglib)
C++17 header-only [PEG](http://en.wikipedia.org/wiki/Parsing_expression_grammar) (Parsing Expression Grammars) library. You can start using it right away just by including `peglib.h` in your project.
@ -33,7 +33,7 @@ The PEG syntax is well described on page 2 in the [document](http://www.brynosau
* `%recovery(` ... `)` (Error recovery operator)
* `exp⇑label` or `exp^label` (Syntax sugar for `(exp / %recover(label))`)
* `label { error_message "..." }` (Error message instruction)
* `{ no_ast_opt }` (No AST node optimazation instruction)
* `{ no_ast_opt }` (No AST node optimization instruction)
'End of Input' check will be done as default. In order to disable the check, please call `disable_eoi_check`.
@ -59,8 +59,8 @@ int main(void) {
// (2) Make a parser
parser parser(R"(
# Grammar for Calculator...
Additive <- Multitive '+' Additive / Multitive
Multitive <- Primary '*' Multitive / Primary
Additive <- Multiplicative '+' Additive / Multiplicative
Multiplicative <- Primary '*' Multiplicative / Primary
Primary <- '(' Additive ')' / Number
Number <- < [0-9]+ >
%whitespace <- [ \t]*
@ -71,16 +71,16 @@ int main(void) {
// (3) Setup actions
parser["Additive"] = [](const SemanticValues &vs) {
switch (vs.choice()) {
case 0: // "Multitive '+' Additive"
case 0: // "Multiplicative '+' Additive"
return any_cast<int>(vs[0]) + any_cast<int>(vs[1]);
default: // "Multitive"
default: // "Multiplicative"
return any_cast<int>(vs[0]);
}
};
parser["Multitive"] = [](const SemanticValues &vs) {
parser["Multiplicative"] = [](const SemanticValues &vs) {
switch (vs.choice()) {
case 0: // "Primary '*' Multitive"
case 0: // "Primary '*' Multiplicative"
return any_cast<int>(vs[0]) * any_cast<int>(vs[1]);
default: // "Primary"
return any_cast<int>(vs[0]);
@ -106,8 +106,8 @@ To show syntax errors in grammar text:
```cpp
auto grammar = R"(
# Grammar for Calculator...
Additive <- Multitive '+' Additive / Multitive
Multitive <- Primary '*' Multitive / Primary
Additive <- Multiplicative '+' Additive / Multiplicative
Multiplicative <- Primary '*' Multiplicative / Primary
Primary <- '(' Additive ')' / Number
Number <- < [0-9]+ >
%whitespace <- [ \t]*
@ -447,8 +447,8 @@ NOTE: An AST node holds a corresponding token as `std::string_vew` for performan
```
peg::parser parser(R"(
...
defenition1 <- ... { no_ast_opt }
defenition2 <- ... { no_ast_opt }
definition1 <- ... { no_ast_opt }
definition2 <- ... { no_ast_opt }
...
)");
@ -659,27 +659,27 @@ usage: grammar_file_path [source_file_path]
```
> cat a.peg
Additive <- Multitive '+' Additive / Multitive
Multitive <- Primary '*' Multitive / Primary
Additive <- Multiplicative '+' Additive / Multiplicative
Multiplicative <- Primary '*' Multiplicative / Primary
Primary <- '(' Additive ')' / Number
%whitespace <- [ \t\r\n]*
> peglint a.peg
[commendline]:3:35: 'Number' is not defined.
[commandline]:3:35: 'Number' is not defined.
```
### Source check
```
> cat a.peg
Additive <- Multitive '+' Additive / Multitive
Multitive <- Primary '*' Multitive / Primary
Additive <- Multiplicative '+' Additive / Multiplicative
Multiplicative <- Primary '*' Multiplicative / Primary
Primary <- '(' Additive ')' / Number
Number <- < [0-9]+ >
%whitespace <- [ \t\r\n]*
> peglint --source "1 + a * 3" a.peg
[commendline]:1:3: syntax error
[commandline]:1:3: syntax error
```
### AST
@ -690,57 +690,57 @@ Number <- < [0-9]+ >
> peglint --ast a.peg a.txt
+ Additive
+ Multitive
+ Multiplicative
+ Primary
- Number (1)
+ Additive
+ Multitive
+ Multiplicative
+ Primary
- Number (2)
+ Multitive
+ Multiplicative
+ Primary
- Number (3)
```
### AST optimazation
### AST optimization
```
> peglint --ast --opt --source "1 + 2 * 3" a.peg
+ Additive
- Multitive[Number] (1)
+ Additive[Multitive]
- Multiplicative[Number] (1)
+ Additive[Multiplicative]
- Primary[Number] (2)
- Multitive[Number] (3)
- Multiplicative[Number] (3)
```
### Adjust AST optimazation with `no_ast_opt` instruction
### Adjust AST optimization with `no_ast_opt` instruction
```
> cat a.peg
Additive <- Multitive '+' Additive / Multitive
Multitive <- Primary '*' Multitive / Primary
Additive <- Multiplicative '+' Additive / Multiplicative
Multiplicative <- Primary '*' Multiplicative / Primary
Primary <- '(' Additive ')' / Number { no_ast_opt }
Number <- < [0-9]+ >
%whitespace <- [ \t\r\n]*
> peglint --ast --opt --source "1 + 2 * 3" a.peg
+ Additive/0
+ Multitive/1[Primary]
+ Multiplicative/1[Primary]
- Number (1)
+ Additive/1[Multitive]
+ Additive/1[Multiplicative]
+ Primary/1
- Number (2)
+ Multitive/1[Primary]
+ Multiplicative/1[Primary]
- Number (3)
> peglint --ast --opt-only --source "1 + 2 * 3" a.peg
+ Additive/0
+ Multitive/1
+ Multiplicative/1
- Primary/1[Number] (1)
+ Additive/1
+ Multitive/0
+ Multiplicative/0
- Primary/1[Number] (2)
+ Multitive/1
+ Multiplicative/1
- Primary/1[Number] (3)
```

@ -1,4 +1,4 @@
// Setup editros
// Setup editors
function setupInfoArea(id) {
const e = ace.edit(id);
e.setShowPrintMargin(false);
@ -26,7 +26,7 @@ const codeAst = setupInfoArea("code-ast");
const codeAstOptimized = setupInfoArea("code-ast-optimized");
const codeProfile = setupInfoArea("code-profile");
$('#opt-mode').val(localStorage.getItem('optimazationMode') || 'all');
$('#opt-mode').val(localStorage.getItem('optimizationMode') || 'all');
$('#packrat').prop('checked', localStorage.getItem('packrat') === 'true');
$('#auto-refresh').prop('checked', localStorage.getItem('autoRefresh') === 'true');
$('#parse').prop('disabled', $('#auto-refresh').prop('checked'));
@ -60,7 +60,7 @@ function generateErrorListHTML(errors) {
function updateLocalStorage() {
localStorage.setItem('grammarText', grammar.getValue());
localStorage.setItem('codeText', code.getValue());
localStorage.setItem('optimazationMode', $('#opt-mode').val());
localStorage.setItem('optimizationMode', $('#opt-mode').val());
localStorage.setItem('packrat', $('#packrat').prop('checked'));
localStorage.setItem('autoRefresh', $('#auto-refresh').prop('checked'));
}
@ -74,7 +74,7 @@ function parse() {
const $codeInfo = $('#code-info');
const codeText = code.getValue();
const optimazationMode = $('#opt-mode').val();
const optimizationMode = $('#opt-mode').val();
const packrat = $('#packrat').prop('checked');
$grammarInfo.html('');
@ -89,7 +89,7 @@ function parse() {
return;
}
const mode = optimazationMode == 'all';
const mode = optimizationMode == 'all';
$('#overlay').css({
'z-index': '1',
@ -132,7 +132,7 @@ function parse() {
}, 0);
}
// Event handing for text editiing
// Event handing for text editing
let timer;
function setupTimer() {
clearTimeout(timer);
@ -163,7 +163,7 @@ function makeOnClickInInfo(editor) {
$('#grammar-info').on('click', 'li', makeOnClickInInfo(grammar));
$('#code-info').on('click', 'li', makeOnClickInInfo(code));
// Event handing in the AST optimazation
// Event handing in the AST optimization
$('#opt-mode').on('change', setupTimer);
$('#packrat').on('change', setupTimer);
$('#auto-refresh').on('change', () => {

@ -9,12 +9,12 @@ int main(void) {
// (2) Make a parser
parser parser(R"(
# Grammar for Calculator...
Additive <- Multitive '+' Additive / Multitive
Multitive <- Primary '*' Multitive^cond / Primary
Additive <- Multiplicative '+' Additive / Multiplicative
Multiplicative <- Primary '*' Multiplicative^cond / Primary
Primary <- '(' Additive ')' / Number
Number <- < [0-9]+ >
%whitespace <- [ \t]*
cond <- '' { error_message "missing multitative" }
cond <- '' { error_message "missing multiplicative" }
)");
assert(static_cast<bool>(parser) == true);
@ -22,16 +22,16 @@ int main(void) {
// (3) Setup actions
parser["Additive"] = [](const SemanticValues &vs) {
switch (vs.choice()) {
case 0: // "Multitive '+' Additive"
case 0: // "Multiplicative '+' Additive"
return any_cast<int>(vs[0]) + any_cast<int>(vs[1]);
default: // "Multitive"
default: // "Multiplicative"
return any_cast<int>(vs[0]);
}
};
parser["Multitive"] = [](const SemanticValues &vs) {
parser["Multiplicative"] = [](const SemanticValues &vs) {
switch (vs.choice()) {
case 0: // "Primary '*' Multitive"
case 0: // "Primary '*' Multiplicative"
return any_cast<int>(vs[0]) * any_cast<int>(vs[1]);
default: // "Primary"
return any_cast<int>(vs[0]);

@ -72,7 +72,7 @@ Char <-
/ "\\u" (((('0' [0-9a-fA-F]) / "10") [0-9a-fA-F]{4,4}) / [0-9a-fA-F]{4,5})
/ !'\\' .
Repetition <- BeginBlacket RepetitionRange EndBlacket
Repetition <- BeginBracket RepetitionRange EndBracket
RepetitionRange <-
Number COMMA Number
@ -124,14 +124,14 @@ Arguments <- OPEN Expression (COMMA Expression)* CLOSE
# Instruction grammars
Instruction <-
BeginBlacket (InstructionItem (InstructionItemSeparator InstructionItem)*)? EndBlacket
BeginBracket (InstructionItem (InstructionItemSeparator InstructionItem)*)? EndBracket
InstructionItem <- PrecedenceClimbing / ErrorMessage / NoAstOpt
~InstructionItemSeparator <- ';' Spacing
~SpacesZom <- Space*
~SpacesOom <- Space+
~BeginBlacket <- '{' Spacing
~EndBlacket <- '}' Spacing
~BeginBracket <- '{' Spacing
~EndBracket <- '}' Spacing
# PrecedenceClimbing instruction
PrecedenceClimbing <- "precedence" SpacesOom PrecedenceInfo (SpacesOom PrecedenceInfo)* SpacesZom
@ -145,5 +145,5 @@ PrecedenceAssoc <- [LR]
# Error message instruction
ErrorMessage <- "message" SpacesOom LiteralD SpacesZom
# No Ast node optimazation instruction
# No Ast node optimization instruction
NoAstOpt <- "no_ast_opt" SpacesZom

@ -9,8 +9,8 @@ usage: grammar_file_path [source_file_path]
options:
--ast: show AST tree
--packrat: enable packrat memoise
--opt, --opt-all: optimaze all AST nodes except nodes selected with `no_ast_opt` instruction
--opt-only: optimaze only AST nodes selected with `no_ast_opt` instruction
--opt, --opt-all: optimize all AST nodes except nodes selected with `no_ast_opt` instruction
--opt-only: optimize only AST nodes selected with `no_ast_opt` instruction
--source: source text
--trace: show concise trace messages
--profile: show profile report
@ -60,14 +60,14 @@ a.peg:3:6: 'A' is left recursive.
```
> cat a.peg
Additive <- Multitive '+' Additive / Multitive
Multitive <- Primary '*' Multitive / Primary
Additive <- Multiplicative '+' Additive / Multiplicative
Multiplicative <- Primary '*' Multiplicative / Primary
Primary <- '(' Additive ')' / Number
Number <- < [0-9]+ >
%whitespace <- [ \t\r\n]*
> peglint --source "1 + a * 3" a.peg
[commendline]:1:3: syntax error
[commandline]:1:3: syntax error
```
### AST
@ -78,56 +78,56 @@ Number <- < [0-9]+ >
> peglint --ast a.peg a.txt
+ Additive
+ Multitive
+ Multiplicative
+ Primary
- Number (1)
+ Additive
+ Multitive
+ Multiplicative
+ Primary
- Number (2)
+ Multitive
+ Multiplicative
+ Primary
- Number (3)
```
### AST optimazation
### AST optimization
```
> peglint --ast --opt --source "1 + 2 * 3" a.peg
+ Additive
- Multitive[Number] (1)
+ Additive[Multitive]
- Multiplicative[Number] (1)
+ Additive[Multiplicative]
- Primary[Number] (2)
- Multitive[Number] (3)
- Multiplicative[Number] (3)
```
### Adjust AST optimazation with `no_ast_opt` instruction
### Adjust AST optimization with `no_ast_opt` instruction
```
> cat a.peg
Additive <- Multitive '+' Additive / Multitive
Multitive <- Primary '*' Multitive / Primary
Additive <- Multiplicative '+' Additive / Multiplicative
Multiplicative <- Primary '*' Multiplicative / Primary
Primary <- '(' Additive ')' / Number { no_ast_opt }
Number <- < [0-9]+ >
%whitespace <- [ \t\r\n]*
> peglint --ast --opt --source "1 + 2 * 3" a.peg
+ Additive/0
+ Multitive/1[Primary]
+ Multiplicative/1[Primary]
- Number (1)
+ Additive/1[Multitive]
+ Additive/1[Multiplicative]
+ Primary/1
- Number (2)
+ Multitive/1[Primary]
+ Multiplicative/1[Primary]
- Number (3)
> peglint --ast --opt-only --source "1 + 2 * 3" a.peg
+ Additive/0
+ Multitive/1
+ Multiplicative/1
- Primary/1[Number] (1)
+ Additive/1
+ Multitive/0
+ Multiplicative/0
- Primary/1[Number] (2)
+ Multitive/1
+ Multiplicative/1
- Primary/1[Number] (3)
```

@ -2506,7 +2506,7 @@ inline size_t parse_literal(const char *s, size_t n, SemanticValues &vs,
}
}
// Skip whiltespace
// Skip whitespace
if (!c.in_token_boundary_count && c.whitespaceOpe) {
auto save_ignore_trace_state = c.ignore_trace_state;
c.ignore_trace_state = !c.verbose_trace;
@ -2691,7 +2691,7 @@ inline size_t Dictionary::parse_core(const char *s, size_t n,
}
}
// Skip whiltespace
// Skip whitespace
if (!c.in_token_boundary_count && c.whitespaceOpe) {
auto save_ignore_trace_state = c.ignore_trace_state;
c.ignore_trace_state = !c.verbose_trace;
@ -3281,7 +3281,7 @@ public:
return parse(s, n, dummy, start, enablePackratParsing, log);
}
// For debuging purpose
// For debugging purpose
static Grammar &grammar() { return get_instance().g; }
private:
@ -3403,7 +3403,7 @@ private:
seq(npd(chr('\\')), dot()));
g["Repetition"] <=
seq(g["BeginBlacket"], g["RepetitionRange"], g["EndBlacket"]);
seq(g["BeginBracket"], g["RepetitionRange"], g["EndBracket"]);
g["RepetitionRange"] <= cho(seq(g["Number"], g["COMMA"], g["Number"]),
seq(g["Number"], g["COMMA"]), g["Number"],
seq(g["COMMA"], g["Number"]));
@ -3455,18 +3455,18 @@ private:
// Instruction grammars
g["Instruction"] <=
seq(g["BeginBlacket"],
seq(g["BeginBracket"],
opt(seq(g["InstructionItem"], zom(seq(g["InstructionItemSeparator"],
g["InstructionItem"])))),
g["EndBlacket"]);
g["EndBracket"]);
g["InstructionItem"] <=
cho(g["PrecedenceClimbing"], g["ErrorMessage"], g["NoAstOpt"]);
~g["InstructionItemSeparator"] <= seq(chr(';'), g["Spacing"]);
~g["SpacesZom"] <= zom(g["Space"]);
~g["SpacesOom"] <= oom(g["Space"]);
~g["BeginBlacket"] <= seq(chr('{'), g["Spacing"]);
~g["EndBlacket"] <= seq(chr('}'), g["Spacing"]);
~g["BeginBracket"] <= seq(chr('{'), g["Spacing"]);
~g["EndBracket"] <= seq(chr('}'), g["Spacing"]);
// PrecedenceClimbing instruction
g["PrecedenceClimbing"] <=
@ -3490,7 +3490,7 @@ private:
g["ErrorMessage"] <= seq(lit("error_message"), g["SpacesOom"],
g["LiteralD"], g["SpacesZom"]);
// No Ast node optimazation instruction
// No Ast node optimization instruction
g["NoAstOpt"] <= seq(lit("no_ast_opt"), g["SpacesZom"]);
// Set definition names

@ -152,7 +152,7 @@ TEST(GeneralTest, String_capture_test3) {
EXPECT_EQ("tag-3", tags[2]);
}
TEST(GeneralTest, Cyclic_grammer_test) {
TEST(GeneralTest, Cyclic_grammar_test) {
Definition PARENT;
Definition CHILD;
@ -507,8 +507,8 @@ TEST(GeneralTest, mutable_lambda_test) {
TEST(GeneralTest, Simple_calculator_test) {
parser parser(R"(
Additive <- Multitive '+' Additive / Multitive
Multitive <- Primary '*' Multitive / Primary
Additive <- Multiplicative '+' Additive / Multiplicative
Multiplicative <- Primary '*' Multiplicative / Primary
Primary <- '(' Additive ')' / Number
Number <- [0-9]+
)");
@ -520,7 +520,7 @@ TEST(GeneralTest, Simple_calculator_test) {
}
};
parser["Multitive"] = [](const SemanticValues &vs) {
parser["Multiplicative"] = [](const SemanticValues &vs) {
switch (vs.choice()) {
case 0: return std::any_cast<int>(vs[0]) * std::any_cast<int>(vs[1]);
default: return std::any_cast<int>(vs[0]);
@ -539,12 +539,12 @@ TEST(GeneralTest, Simple_calculator_test) {
TEST(GeneralTest, Simple_calculator_with_recovery_test) {
parser parser(R"(
Additive <- Multitive '+' Additive / Multitive
Multitive <- Primary '*' Multitive^cond / Primary
Additive <- Multiplicative '+' Additive / Multiplicative
Multiplicative <- Primary '*' Multiplicative^cond / Primary
Primary <- '(' Additive ')' / Number
Number <- < [0-9]+ >
%whitespace <- [ \t]*
cond <- '' { error_message "missing multitative" }
cond <- '' { error_message "missing multiplicative" }
)");
parser["Additive"] = [](const SemanticValues &vs) {
@ -554,7 +554,7 @@ TEST(GeneralTest, Simple_calculator_with_recovery_test) {
}
};
parser["Multitive"] = [](const SemanticValues &vs) {
parser["Multiplicative"] = [](const SemanticValues &vs) {
switch (vs.choice()) {
case 0: return std::any_cast<int>(vs[0]) * std::any_cast<int>(vs[1]);
default: return std::any_cast<int>(vs[0]);
@ -573,7 +573,7 @@ TEST(GeneralTest, Simple_calculator_with_recovery_test) {
}
TEST(GeneralTest, Calculator_test) {
// Construct grammer
// Construct grammar
Definition EXPRESSION, TERM, FACTOR, TERM_OPERATOR, FACTOR_OPERATOR, NUMBER;
EXPRESSION <= seq(TERM, zom(seq(TERM_OPERATOR, TERM)));
@ -753,7 +753,7 @@ TEST(GeneralTest, Calculator_test_with_AST) {
}
TEST(GeneralTest, Calculator_test_with_combinators_and_AST) {
// Construct grammer
// Construct grammar
AST_DEFINITIONS(EXPRESSION, TERM, FACTOR, TERM_OPERATOR, FACTOR_OPERATOR,
NUMBER);

@ -1822,7 +1822,7 @@ PRINTLN ← 'System.out.println'
# Throw operator labels
rcblk SkipToRCUR { error_message "missing end of block." }
semia '' { error_message "missing simicolon in assignment." }
semia '' { error_message "missing semicolon in assignment." }
# Recovery expressions
SkipToRCUR (!RCUR (LCUR SkipToRCUR / .))* RCUR
@ -1831,7 +1831,7 @@ SkipToRCUR ← (!RCUR (LCUR SkipToRCUR / .))* RCUR
EXPECT_TRUE(!!pg);
std::vector<std::string> errors{
R"(8:5: missing simicolon in assignment.)",
R"(8:5: missing semicolon in assignment.)",
R"(8:6: missing end of block.)",
};

Loading…
Cancel
Save