mirror of
https://github.com/yhirose/cpp-peglib.git
synced 2024-12-22 11:55:30 +00:00
Uploaded files.
This commit is contained in:
parent
0d57c6acc9
commit
1ad9e73d67
4
.gitignore
vendored
4
.gitignore
vendored
@ -26,3 +26,7 @@
|
|||||||
*.exe
|
*.exe
|
||||||
*.out
|
*.out
|
||||||
*.app
|
*.app
|
||||||
|
|
||||||
|
# Others
|
||||||
|
*.dSYM
|
||||||
|
*.swp
|
||||||
|
182
README.md
182
README.md
@ -1,2 +1,180 @@
|
|||||||
# cpp-peglib
|
cpp-peglib
|
||||||
A C++11 header-only PEG (Parsing Expression Grammars) library
|
==========
|
||||||
|
|
||||||
|
C++11 header-only [PEG](http://en.wikipedia.org/wiki/Parsing_expression_grammar) (Parsing Expression Grammars) library.
|
||||||
|
|
||||||
|
*cpp-peglib* tries to provide more expressive parsing experience than common regular expression libraries such as std::regex. It also keeps it in mind that users can easily start using it.
|
||||||
|
|
||||||
|
The PEG syntax that *cpp-peglib* understands is described on page 2 in the [document](http://pdos.csail.mit.edu/papers/parsing:popl04.pdf).
|
||||||
|
|
||||||
|
How to use
|
||||||
|
----------
|
||||||
|
|
||||||
|
What if we want to extract only tag names in brackets from ` [tag1] [tag2] [tag3] [tag4]... `? It's a bit hard to do it with `std::regex`. We have to write a loop logic, since it doesn't support [Repeated Captures](http://www.boost.org/doc/libs/1_57_0/libs/regex/doc/html/boost_regex/captures.html#boost_regex.captures.repeated_captures). PEG can handle it pretty easily.
|
||||||
|
|
||||||
|
PEG grammar for this task could be like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
ROOT <- _ ('[' TAG_NAME ']' _)*
|
||||||
|
TAG_NAME <- (!']' .)+
|
||||||
|
_ <- [ \t]*
|
||||||
|
```
|
||||||
|
|
||||||
|
Here is how to parse text with the PEG syntax and retreive tag names:
|
||||||
|
|
||||||
|
|
||||||
|
```c++
|
||||||
|
// (1) Include the header file
|
||||||
|
#include "peglib.h"
|
||||||
|
|
||||||
|
// (2) Make a parser
|
||||||
|
auto parser = peglib::make_parser(R"(
|
||||||
|
ROOT <- _ ('[' TAG_NAME ']' _)*
|
||||||
|
TAG_NAME <- (!']' .)+
|
||||||
|
_ <- [ \t]*
|
||||||
|
)");
|
||||||
|
|
||||||
|
// (3) Setup an action
|
||||||
|
std::vector<std::string> tags;
|
||||||
|
parser["TAG_NAME"] = [&](const char* s, size_t l) {
|
||||||
|
tags.push_back(std::string(s, l));
|
||||||
|
};
|
||||||
|
|
||||||
|
// (4) Parse
|
||||||
|
auto ret = parser.parse(" [tag1] [tag:2] [tag-3] ");
|
||||||
|
|
||||||
|
assert(ret == true);
|
||||||
|
assert(tags[0] == "tag1");
|
||||||
|
assert(tags[1] == "tag:2");
|
||||||
|
assert(tags[2] == "tag-3");
|
||||||
|
```
|
||||||
|
|
||||||
|
You may have a question regarding '(3) Setup an action'. When the parser recognizes the definition 'TAG_NAME', it calls back the action `[&](const char* s, size_t l)` where `const char* s, size_t l` refers to the matched string, so that the user could use the string for something else.
|
||||||
|
|
||||||
|
We can do more with actions. A more complex example is here:
|
||||||
|
|
||||||
|
```c++
|
||||||
|
// Calculator example
|
||||||
|
using namespace peglib;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
auto parser = make_parser(R"(
|
||||||
|
# Grammar for Calculator...
|
||||||
|
EXPRESSION <- TERM (TERM_OPERATOR TERM)*
|
||||||
|
TERM <- FACTOR (FACTOR_OPERATOR FACTOR)*
|
||||||
|
FACTOR <- NUMBER / '(' EXPRESSION ')'
|
||||||
|
TERM_OPERATOR <- [-+]
|
||||||
|
FACTOR_OPERATOR <- [/*]
|
||||||
|
NUMBER <- [0-9]+
|
||||||
|
)");
|
||||||
|
|
||||||
|
auto reduce = [](const vector<Any>& v) -> long {
|
||||||
|
long ret = v[0].get<long>();
|
||||||
|
for (auto i = 1u; i < v.size(); i += 2) {
|
||||||
|
auto num = v[i + 1].get<long>();
|
||||||
|
switch (v[i].get<char>()) {
|
||||||
|
case '+': ret += num; break;
|
||||||
|
case '-': ret -= num; break;
|
||||||
|
case '*': ret *= num; break;
|
||||||
|
case '/': ret /= num; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
parser["EXPRESSION"] = reduce;
|
||||||
|
parser["TERM"] = reduce;
|
||||||
|
parser["TERM_OPERATOR"] = [](const char* s, size_t l) { return (char)*s; };
|
||||||
|
parser["FACTOR_OPERATOR"] = [](const char* s, size_t l) { return (char)*s; };
|
||||||
|
parser["NUMBER"] = [](const char* s, size_t l) { return stol(string(s, l), nullptr, 10); };
|
||||||
|
|
||||||
|
long val;
|
||||||
|
auto ret = parser.parse("1+2*3*(4-5+6)/7-8", val);
|
||||||
|
|
||||||
|
assert(ret == true);
|
||||||
|
assert(val == -3);
|
||||||
|
```
|
||||||
|
|
||||||
|
It may be helpful to keep in mind that the action behavior is similar to the YACC semantic action model ($$ = $1, $2, ...).
|
||||||
|
|
||||||
|
In this example, the actions return values. These samentic values will be pushed up to the parent definition which can be referred to in the parent action `[](const vector<Any>& v)`. In other words, when a certain definition has been accepted, we can find all semantic values which are associated with the child definitions in `const vector<Any>& v`. The values are wrapped by peblib::Any class which is like `boost::any`. We can retrieve the value by using `get<T>` method where `T` is the actual type of the value. If no value is returned in an action, an undefined `Any` will be pushed up to the parent. Finally, the resulting value of the root definition is received in the out parameter of `parse` method in the parser. `long val` is the resulting value in this case.
|
||||||
|
|
||||||
|
Here are available user actions:
|
||||||
|
|
||||||
|
```c++
|
||||||
|
[](const char* s, size_t l, const std::vector<peglib::Any>& v, const std::vector<std::string>& n)
|
||||||
|
[](const char* s, size_t l, const std::vector<peglib::Any>& v)
|
||||||
|
[](const char* s, size_t l)
|
||||||
|
[](const std::vector<peglib::Any>& v, const std::vector<std::string>& n)
|
||||||
|
[](const std::vector<peglib::Any>& v)
|
||||||
|
[]()
|
||||||
|
```
|
||||||
|
|
||||||
|
`const std::vector<std::string>& n` holds names of child definitions that could be helpful when we want to check what are the actual child definitions.
|
||||||
|
|
||||||
|
Make a parser with parser operators and simple actions
|
||||||
|
------------------------------------------------------
|
||||||
|
|
||||||
|
Instead of makeing a parser by parsing PEG syntax text, we can also construct a parser by hand with *parser operators* and use the *simple action* method rather than the semantic action method. Here is an example:
|
||||||
|
|
||||||
|
```c++
|
||||||
|
using namespace peglib;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
Definition ROOT, TAG, TAG_NAME, _;
|
||||||
|
ROOT = seq(_, zom(TAG));
|
||||||
|
TAG = seq(chr('['), TAG_NAME, chr(']'), _);
|
||||||
|
TAG_NAME = oom(seq(npd(chr(']')), any()));
|
||||||
|
_ = zom(cls(" \t"));
|
||||||
|
|
||||||
|
vector<string> tags;
|
||||||
|
TAG_NAME.match = [&](const char* s, size_t l) {
|
||||||
|
tags.push_back(string(s, l));
|
||||||
|
};
|
||||||
|
|
||||||
|
auto ret = ROOT.parse(" [tag1] [tag:2] [tag-3] ");
|
||||||
|
```
|
||||||
|
|
||||||
|
In fact, the PEG parser generator is made with operators. You can see the code at `make_peg_grammar` function in `peglib.h`.
|
||||||
|
|
||||||
|
The following are available operators:
|
||||||
|
|
||||||
|
| Description | Operator |
|
||||||
|
|--------------------|----------|
|
||||||
|
| Sequence | seq |
|
||||||
|
| Prioritized Choice | cho |
|
||||||
|
| Grouping | grp |
|
||||||
|
| Zero or More | zom |
|
||||||
|
| One or More | oom |
|
||||||
|
| Optional | opt |
|
||||||
|
| And predicate | apd |
|
||||||
|
| Not predicate | npd |
|
||||||
|
| Literal string | lit |
|
||||||
|
| Character class | cls |
|
||||||
|
| Character | chr |
|
||||||
|
| Any character | any |
|
||||||
|
|
||||||
|
Tested Compilers
|
||||||
|
----------------
|
||||||
|
|
||||||
|
* Visual Studio 2013
|
||||||
|
* Clang 3.5
|
||||||
|
|
||||||
|
TODO
|
||||||
|
----
|
||||||
|
|
||||||
|
* Linear-time parsing (Packrat parsing)
|
||||||
|
* Optimization of grammars
|
||||||
|
* Unicode support
|
||||||
|
|
||||||
|
Other C++ PEG parser libraries that inspired cpp-peblib
|
||||||
|
-------------------------------------------------------
|
||||||
|
|
||||||
|
* [PEGTL](https://github.com/ColinH/PEGTL) - Parsing Expression Grammar Template Library
|
||||||
|
* [lars::Parser](https://github.com/TheLartians/Parser) - A header-only linear-time c++ parsing expression grammar (PEG) parser generator supporting left-recursion and grammar ambiguity
|
||||||
|
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
|
||||||
|
MIT license (© 2015 Yuji Hirose)
|
||||||
|
18
example/Makefile
Normal file
18
example/Makefile
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
|
||||||
|
USE_CLANG = 1
|
||||||
|
|
||||||
|
ifdef USE_CLANG
|
||||||
|
CC = clang++
|
||||||
|
CFLAGS = -std=c++1y -stdlib=libc++ -g
|
||||||
|
else
|
||||||
|
CC = g++-4.9
|
||||||
|
CFLAGS = -std=c++1y -g
|
||||||
|
endif
|
||||||
|
|
||||||
|
all: calc calc2
|
||||||
|
|
||||||
|
calc : calc.cc ../peglib.h
|
||||||
|
$(CC) -o calc $(CFLAGS) -I.. calc.cc
|
||||||
|
|
||||||
|
calc2 : calc2.cc ../peglib.h
|
||||||
|
$(CC) -o calc2 $(CFLAGS) -I.. calc2.cc
|
92
example/calc.cc
Normal file
92
example/calc.cc
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
//
|
||||||
|
// calc.cc
|
||||||
|
//
|
||||||
|
// Copyright (c) 2015 Yuji Hirose. All rights reserved.
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <peglib.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
using namespace peglib;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
//
|
||||||
|
// PEG syntax:
|
||||||
|
//
|
||||||
|
// EXPRESSION <- TERM (TERM_OPERATOR TERM)*
|
||||||
|
// TERM <- FACTOR (FACTOR_OPERATOR FACTOR)*
|
||||||
|
// FACTOR <- NUMBER / '(' EXPRESSION ')'
|
||||||
|
// TERM_OPERATOR <- [-+]
|
||||||
|
// FACTOR_OPERATOR <- [/*]
|
||||||
|
// NUMBER <- [0-9]+
|
||||||
|
//
|
||||||
|
class Calculator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Calculator() {
|
||||||
|
const char* syntax =
|
||||||
|
" EXPRESSION <- TERM (TERM_OPERATOR TERM)* "
|
||||||
|
" TERM <- FACTOR (FACTOR_OPERATOR FACTOR)* "
|
||||||
|
" FACTOR <- NUMBER / '(' EXPRESSION ')' "
|
||||||
|
" TERM_OPERATOR <- [-+] "
|
||||||
|
" FACTOR_OPERATOR <- [/*] "
|
||||||
|
" NUMBER <- [0-9]+ "
|
||||||
|
;
|
||||||
|
|
||||||
|
parser.load_syntax(syntax);
|
||||||
|
|
||||||
|
parser["EXPRESSION"] = reduce;
|
||||||
|
parser["TERM"] = reduce;
|
||||||
|
parser["TERM_OPERATOR"] = [](const char* s, size_t l) { return (char)*s; };
|
||||||
|
parser["FACTOR_OPERATOR"] = [](const char* s, size_t l) { return (char)*s; };
|
||||||
|
parser["NUMBER"] = [](const char* s, size_t l) { return stol(string(s, l), nullptr, 10); };
|
||||||
|
}
|
||||||
|
|
||||||
|
bool execute(const char* s, long& v) const {
|
||||||
|
return parser.parse(s, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Parser parser;
|
||||||
|
|
||||||
|
static long reduce(const vector<Any>& v) {
|
||||||
|
auto result = v[0].get<long>();
|
||||||
|
for (auto i = 1u; i < v.size(); i += 2) {
|
||||||
|
auto num = v[i + 1].get<long>();
|
||||||
|
auto ope = v[i].get<char>();
|
||||||
|
switch (ope) {
|
||||||
|
case '+': result += num; break;
|
||||||
|
case '-': result -= num; break;
|
||||||
|
case '*': result *= num; break;
|
||||||
|
case '/': result /= num; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, const char** argv)
|
||||||
|
{
|
||||||
|
if (argc < 2 || string("--help") == argv[1]) {
|
||||||
|
cout << "usage: calc [formula]" << endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* s = argv[1];
|
||||||
|
|
||||||
|
Calculator calc;
|
||||||
|
|
||||||
|
long val = 0;
|
||||||
|
if (calc.execute(s, val)) {
|
||||||
|
cout << s << " = " << val << endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << "syntax error..." << endl;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// vim: et ts=4 sw=4 cin cino={1s ff=unix
|
92
example/calc.vcxproj
Normal file
92
example/calc.vcxproj
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\peglib.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="calc.cc" />
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{F85B641A-7538-4809-8175-C528FF632CF6}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<RootNamespace>sample</RootNamespace>
|
||||||
|
<ProjectName>calc</ProjectName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>..</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>..</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
94
example/calc2.cc
Normal file
94
example/calc2.cc
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
//
|
||||||
|
// calc2.cc
|
||||||
|
//
|
||||||
|
// Copyright (c) 2015 Yuji Hirose. All rights reserved.
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <peglib.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
using namespace peglib;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
//
|
||||||
|
// PEG syntax:
|
||||||
|
//
|
||||||
|
// EXPRESSION <- TERM (TERM_OPERATOR TERM)*
|
||||||
|
// TERM <- FACTOR (FACTOR_OPERATOR FACTOR)*
|
||||||
|
// FACTOR <- NUMBER / '(' EXPRESSION ')'
|
||||||
|
// TERM_OPERATOR <- [-+]
|
||||||
|
// FACTOR_OPERATOR <- [/*]
|
||||||
|
// NUMBER <- [0-9]+
|
||||||
|
//
|
||||||
|
class Calculator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Calculator() {
|
||||||
|
EXPRESSION = seq(TERM, zom(seq(TERM_OPERATOR, TERM)));
|
||||||
|
TERM = seq(FACTOR, zom(seq(FACTOR_OPERATOR, FACTOR)));
|
||||||
|
FACTOR = cho(NUMBER, seq(chr('('), EXPRESSION, chr(')')));
|
||||||
|
TERM_OPERATOR = cls("+-");
|
||||||
|
FACTOR_OPERATOR = cls("*/");
|
||||||
|
NUMBER = oom(cls("0-9"));
|
||||||
|
|
||||||
|
actions[EXPRESSION] = reduce;
|
||||||
|
actions[TERM] = reduce;
|
||||||
|
actions[TERM_OPERATOR] = [](const char* s, size_t l) { return (char)*s; };
|
||||||
|
actions[FACTOR_OPERATOR] = [](const char* s, size_t l) { return (char)*s; };
|
||||||
|
actions[NUMBER] = [](const char* s, size_t l) { return stol(string(s, l), nullptr, 10); };
|
||||||
|
}
|
||||||
|
|
||||||
|
bool execute(const char* s, long& v) const {
|
||||||
|
Any val;
|
||||||
|
auto ret = EXPRESSION.parse(s, actions, val);
|
||||||
|
if (ret) {
|
||||||
|
v = val.get<long>();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Definition EXPRESSION, TERM, FACTOR, TERM_OPERATOR, FACTOR_OPERATOR, NUMBER;
|
||||||
|
SemanticActions<Any> actions;
|
||||||
|
|
||||||
|
static long reduce(const vector<Any>& v) {
|
||||||
|
auto result = v[0].get<long>();
|
||||||
|
for (auto i = 1u; i < v.size(); i += 2) {
|
||||||
|
auto num = v[i + 1].get<long>();
|
||||||
|
auto ope = v[i].get<char>();
|
||||||
|
switch (ope) {
|
||||||
|
case '+': result += num; break;
|
||||||
|
case '-': result -= num; break;
|
||||||
|
case '*': result *= num; break;
|
||||||
|
case '/': result /= num; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, const char** argv)
|
||||||
|
{
|
||||||
|
if (argc < 2 || string("--help") == argv[1]) {
|
||||||
|
cout << "usage: calc [formula]" << endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* s = argv[1];
|
||||||
|
|
||||||
|
Calculator calc;
|
||||||
|
|
||||||
|
long val = 0;
|
||||||
|
if (calc.execute(s, val)) {
|
||||||
|
cout << s << " = " << val << endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << "syntax error..." << endl;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// vim: et ts=4 sw=4 cin cino={1s ff=unix
|
92
example/calc2.vcxproj
Normal file
92
example/calc2.vcxproj
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\peglib.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="calc2.cc" />
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{1D09607B-E1C0-4D62-8AB4-9E2D2C2DC6E4}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<RootNamespace>sample</RootNamespace>
|
||||||
|
<ProjectName>calc2</ProjectName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>..</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>..</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
28
example/example.sln
Normal file
28
example/example.sln
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio 2013
|
||||||
|
VisualStudioVersion = 12.0.31101.0
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "calc", "calc.vcxproj", "{F85B641A-7538-4809-8175-C528FF632CF6}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "calc", "calc2.vcxproj", "{1D09607B-E1C0-4D62-8AB4-9E2D2C2DC6E4}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Win32 = Debug|Win32
|
||||||
|
Release|Win32 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{F85B641A-7538-4809-8175-C528FF632CF6}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{F85B641A-7538-4809-8175-C528FF632CF6}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{F85B641A-7538-4809-8175-C528FF632CF6}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{F85B641A-7538-4809-8175-C528FF632CF6}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{1D09607B-E1C0-4D62-8AB4-9E2D2C2DC6E4}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{1D09607B-E1C0-4D62-8AB4-9E2D2C2DC6E4}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{1D09607B-E1C0-4D62-8AB4-9E2D2C2DC6E4}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{1D09607B-E1C0-4D62-8AB4-9E2D2C2DC6E4}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
9
test/Makefile
Normal file
9
test/Makefile
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
CC = clang++
|
||||||
|
CCFLAGS = -std=c++11 -stdlib=libc++ -g
|
||||||
|
|
||||||
|
all : test
|
||||||
|
./test
|
||||||
|
|
||||||
|
test : test.cc ../peglib.h
|
||||||
|
$(CC) -o test $(CCFLAGS) -I.. -I. test.cc
|
8974
test/catch.hpp
Normal file
8974
test/catch.hpp
Normal file
File diff suppressed because it is too large
Load Diff
505
test/test.cc
Normal file
505
test/test.cc
Normal file
@ -0,0 +1,505 @@
|
|||||||
|
|
||||||
|
#define CATCH_CONFIG_MAIN
|
||||||
|
#include "catch.hpp"
|
||||||
|
|
||||||
|
#include <peglib.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
TEST_CASE("String capture test", "[general]")
|
||||||
|
{
|
||||||
|
{
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER < 1900 // Less than Visual Studio 2015
|
||||||
|
auto parser = peglib::make_parser(
|
||||||
|
" ROOT <- _ ('[' TAG_NAME ']' _)* "
|
||||||
|
" TAG_NAME <- (!']' .)+ "
|
||||||
|
" _ <- [ \t]* "
|
||||||
|
);
|
||||||
|
#else
|
||||||
|
auto parser = peglib::make_parser(R"(
|
||||||
|
ROOT <- _ ('[' TAG_NAME ']' _)*
|
||||||
|
TAG_NAME <- (!']' .)+
|
||||||
|
_ <- [ \t]*
|
||||||
|
)");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::vector<std::string> tags;
|
||||||
|
|
||||||
|
parser["TAG_NAME"] = [&](const char* s, size_t l) {
|
||||||
|
tags.push_back(std::string(s, l));
|
||||||
|
};
|
||||||
|
|
||||||
|
auto ret = parser.parse(" [tag1] [tag:2] [tag-3] ");
|
||||||
|
|
||||||
|
REQUIRE(ret == true);
|
||||||
|
REQUIRE(tags.size() == 3);
|
||||||
|
REQUIRE(tags[0] == "tag1");
|
||||||
|
REQUIRE(tags[1] == "tag:2");
|
||||||
|
REQUIRE(tags[2] == "tag-3");
|
||||||
|
}
|
||||||
|
|
||||||
|
REQUIRE(peglib::VARINT_COUNT == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace peglib;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
TEST_CASE("String capture test with match", "[general]")
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Definition ROOT, TAG, TAG_NAME, WS;
|
||||||
|
|
||||||
|
ROOT = seq(WS, zom(TAG));
|
||||||
|
TAG = seq(chr('['), TAG_NAME, chr(']'), WS);
|
||||||
|
TAG_NAME = oom(seq(npd(chr(']')), any()));
|
||||||
|
WS = zom(cls(" \t"));
|
||||||
|
|
||||||
|
vector<string> tags;
|
||||||
|
|
||||||
|
TAG_NAME.match = [&](const char* s, size_t l) {
|
||||||
|
tags.push_back(string(s, l));
|
||||||
|
};
|
||||||
|
|
||||||
|
auto ret = ROOT.parse(" [tag1] [tag:2] [tag-3] ");
|
||||||
|
|
||||||
|
REQUIRE(ret == true);
|
||||||
|
REQUIRE(tags.size() == 3);
|
||||||
|
REQUIRE(tags[0] == "tag1");
|
||||||
|
REQUIRE(tags[1] == "tag:2");
|
||||||
|
REQUIRE(tags[2] == "tag-3");
|
||||||
|
}
|
||||||
|
|
||||||
|
REQUIRE(VARINT_COUNT == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Cyclic grammer test", "[general]")
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Definition PARENT;
|
||||||
|
Definition CHILD;
|
||||||
|
|
||||||
|
PARENT = seq(CHILD);
|
||||||
|
CHILD = seq(PARENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
REQUIRE(VARINT_COUNT == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Lambda action test", "[general]")
|
||||||
|
{
|
||||||
|
auto parser = make_parser(
|
||||||
|
" START <- (CHAR)* "
|
||||||
|
" CHAR <- . ");
|
||||||
|
|
||||||
|
string ss;
|
||||||
|
parser["CHAR"] = [&](const char* s, size_t l) {
|
||||||
|
ss += *s;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool ret = parser.parse("hello");
|
||||||
|
REQUIRE(ret == true);
|
||||||
|
REQUIRE(ss == "hello");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Calculator test", "[general]")
|
||||||
|
{
|
||||||
|
{
|
||||||
|
// Construct grammer
|
||||||
|
Definition EXPRESSION, TERM, FACTOR, TERM_OPERATOR, FACTOR_OPERATOR, NUMBER;
|
||||||
|
|
||||||
|
EXPRESSION = seq(TERM, zom(seq(TERM_OPERATOR, TERM)));
|
||||||
|
TERM = seq(FACTOR, zom(seq(FACTOR_OPERATOR, FACTOR)));
|
||||||
|
FACTOR = cho(NUMBER, seq(chr('('), EXPRESSION, chr(')')));
|
||||||
|
TERM_OPERATOR = cls("+-");
|
||||||
|
FACTOR_OPERATOR = cls("*/");
|
||||||
|
NUMBER = oom(cls("0-9"));
|
||||||
|
|
||||||
|
// Setup actions
|
||||||
|
SemanticActions<Any> actions;
|
||||||
|
|
||||||
|
auto reduce = [](const vector<Any>& v) -> long {
|
||||||
|
long ret = v[0].get<long>();
|
||||||
|
for (auto i = 1u; i < v.size(); i += 2) {
|
||||||
|
auto num = v[i + 1].get<long>();
|
||||||
|
switch (v[i].get<char>()) {
|
||||||
|
case '+': ret += num; break;
|
||||||
|
case '-': ret -= num; break;
|
||||||
|
case '*': ret *= num; break;
|
||||||
|
case '/': ret /= num; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
actions[EXPRESSION] = reduce;
|
||||||
|
actions[TERM] = reduce;
|
||||||
|
actions[TERM_OPERATOR] = [](const char* s, size_t l) { return *s; };
|
||||||
|
actions[FACTOR_OPERATOR] = [](const char* s, size_t l) { return *s; };
|
||||||
|
actions[NUMBER] = [&](const char* s, size_t l) { return stol(string(s, l), nullptr, 10); };
|
||||||
|
|
||||||
|
// Parse
|
||||||
|
Any val;
|
||||||
|
auto ret = EXPRESSION.parse("1+2*3*(4-5+6)/7-8", actions, val);
|
||||||
|
|
||||||
|
REQUIRE(ret == true);
|
||||||
|
REQUIRE(val.get<long>() == -3);
|
||||||
|
}
|
||||||
|
|
||||||
|
REQUIRE(VARINT_COUNT == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Calculator test2", "[general]")
|
||||||
|
{
|
||||||
|
{
|
||||||
|
// Parse syntax
|
||||||
|
auto syntax =
|
||||||
|
" # Grammar for Calculator...\n "
|
||||||
|
" EXPRESSION <- TERM (TERM_OPERATOR TERM)* "
|
||||||
|
" TERM <- FACTOR (FACTOR_OPERATOR FACTOR)* "
|
||||||
|
" FACTOR <- NUMBER / '(' EXPRESSION ')' "
|
||||||
|
" TERM_OPERATOR <- [-+] "
|
||||||
|
" FACTOR_OPERATOR <- [/*] "
|
||||||
|
" NUMBER <- [0-9]+ "
|
||||||
|
;
|
||||||
|
|
||||||
|
string start;
|
||||||
|
auto grammar = make_grammar(syntax, start);
|
||||||
|
auto& g = *grammar;
|
||||||
|
|
||||||
|
// Setup actions
|
||||||
|
SemanticActions<Any> a;
|
||||||
|
|
||||||
|
auto reduce = [](const vector<Any>& v) -> long {
|
||||||
|
long ret = v[0].get<long>();
|
||||||
|
for (auto i = 1u; i < v.size(); i += 2) {
|
||||||
|
auto num = v[i + 1].get<long>();
|
||||||
|
switch (v[i].get<char>()) {
|
||||||
|
case '+': ret += num; break;
|
||||||
|
case '-': ret -= num; break;
|
||||||
|
case '*': ret *= num; break;
|
||||||
|
case '/': ret /= num; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
a[g["EXPRESSION"]] = reduce;
|
||||||
|
a[g["TERM"]] = reduce;
|
||||||
|
a[g["TERM_OPERATOR"]] = [](const char* s, size_t l) { return *s; };
|
||||||
|
a[g["FACTOR_OPERATOR"]] = [](const char* s, size_t l) { return *s; };
|
||||||
|
a[g["NUMBER"]] = [&](const char* s, size_t l) { return stol(string(s, l), nullptr, 10); };
|
||||||
|
|
||||||
|
// Parse
|
||||||
|
Any val;
|
||||||
|
auto ret = g[start].parse("1+2*3*(4-5+6)/7-8", a, val);
|
||||||
|
|
||||||
|
REQUIRE(ret == true);
|
||||||
|
REQUIRE(val.get<long>() == -3);
|
||||||
|
}
|
||||||
|
|
||||||
|
REQUIRE(VARINT_COUNT == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Calculator test3", "[general]")
|
||||||
|
{
|
||||||
|
{
|
||||||
|
// Parse syntax
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER < 1900 // Less than Visual Studio 2015
|
||||||
|
auto parser = make_parser(
|
||||||
|
" # Grammar for Calculator...\n "
|
||||||
|
" EXPRESSION <- TERM (TERM_OPERATOR TERM)* "
|
||||||
|
" TERM <- FACTOR (FACTOR_OPERATOR FACTOR)* "
|
||||||
|
" FACTOR <- NUMBER / '(' EXPRESSION ')' "
|
||||||
|
" TERM_OPERATOR <- [-+] "
|
||||||
|
" FACTOR_OPERATOR <- [/*] "
|
||||||
|
" NUMBER <- [0-9]+ "
|
||||||
|
);
|
||||||
|
#else
|
||||||
|
auto parser = make_parser(R"(
|
||||||
|
# Grammar for Calculator...
|
||||||
|
EXPRESSION <- TERM (TERM_OPERATOR TERM)*
|
||||||
|
TERM <- FACTOR (FACTOR_OPERATOR FACTOR)*
|
||||||
|
FACTOR <- NUMBER / '(' EXPRESSION ')'
|
||||||
|
TERM_OPERATOR <- [-+]
|
||||||
|
FACTOR_OPERATOR <- [/*]
|
||||||
|
NUMBER <- [0-9]+
|
||||||
|
)");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
auto reduce = [](const vector<Any>& v) -> long {
|
||||||
|
long ret = v[0].get<long>();
|
||||||
|
for (auto i = 1u; i < v.size(); i += 2) {
|
||||||
|
auto num = v[i + 1].get<long>();
|
||||||
|
switch (v[i].get<char>()) {
|
||||||
|
case '+': ret += num; break;
|
||||||
|
case '-': ret -= num; break;
|
||||||
|
case '*': ret *= num; break;
|
||||||
|
case '/': ret /= num; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Setup actions
|
||||||
|
parser["EXPRESSION"] = reduce;
|
||||||
|
parser["TERM"] = reduce;
|
||||||
|
parser["TERM_OPERATOR"] = [](const char* s, size_t l) { return (char)*s; };
|
||||||
|
parser["FACTOR_OPERATOR"] = [](const char* s, size_t l) { return (char)*s; };
|
||||||
|
parser["NUMBER"] = [](const char* s, size_t l) { return stol(string(s, l), nullptr, 10); };
|
||||||
|
|
||||||
|
// Parse
|
||||||
|
long val;
|
||||||
|
auto ret = parser.parse("1+2*3*(4-5+6)/7-8", val);
|
||||||
|
|
||||||
|
REQUIRE(ret == true);
|
||||||
|
REQUIRE(val == -3);
|
||||||
|
}
|
||||||
|
|
||||||
|
REQUIRE(VARINT_COUNT == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("PEG Grammar", "[peg]")
|
||||||
|
{
|
||||||
|
Grammar g = make_peg_grammar();
|
||||||
|
REQUIRE(g["Grammar"].parse(" Definition <- a / ( b c ) / d \n rule2 <- [a-zA-Z][a-z0-9-]+ ") == true);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("PEG Definition", "[peg]")
|
||||||
|
{
|
||||||
|
Grammar g = make_peg_grammar();
|
||||||
|
REQUIRE(g["Definition"].parse("Definition <- a / (b c) / d ") == true);
|
||||||
|
REQUIRE(g["Definition"].parse("Definition <- a / b c / d ") == true);
|
||||||
|
REQUIRE(g["Definition"].parse("Definition ") == false);
|
||||||
|
REQUIRE(g["Definition"].parse(" ") == false);
|
||||||
|
REQUIRE(g["Definition"].parse("") == false);
|
||||||
|
REQUIRE(g["Definition"].parse("Definition = a / (b c) / d ") == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("PEG Expression", "[peg]")
|
||||||
|
{
|
||||||
|
Grammar g = make_peg_grammar();
|
||||||
|
REQUIRE(g["Expression"].parse("a / (b c) / d ") == true);
|
||||||
|
REQUIRE(g["Expression"].parse("a / b c / d ") == true);
|
||||||
|
REQUIRE(g["Expression"].parse("a b ") == true);
|
||||||
|
REQUIRE(g["Expression"].parse("") == true);
|
||||||
|
REQUIRE(g["Expression"].parse(" ") == false);
|
||||||
|
REQUIRE(g["Expression"].parse(" a b ") == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("PEG Sequence", "[peg]")
|
||||||
|
{
|
||||||
|
Grammar g = make_peg_grammar();
|
||||||
|
REQUIRE(g["Sequence"].parse("a b c d ") == true);
|
||||||
|
REQUIRE(g["Sequence"].parse("") == true);
|
||||||
|
REQUIRE(g["Sequence"].parse("!") == false);
|
||||||
|
REQUIRE(g["Sequence"].parse("<-") == false);
|
||||||
|
REQUIRE(g["Sequence"].parse(" a") == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("PEG Prefix", "[peg]")
|
||||||
|
{
|
||||||
|
Grammar g = make_peg_grammar();
|
||||||
|
REQUIRE(g["Prefix"].parse("&[a]") == true);
|
||||||
|
REQUIRE(g["Prefix"].parse("![']") == true);
|
||||||
|
REQUIRE(g["Prefix"].parse("-[']") == false);
|
||||||
|
REQUIRE(g["Prefix"].parse("") == false);
|
||||||
|
REQUIRE(g["Sequence"].parse(" a") == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("PEG Suffix", "[peg]")
|
||||||
|
{
|
||||||
|
Grammar g = make_peg_grammar();
|
||||||
|
REQUIRE(g["Suffix"].parse("aaa ") == true);
|
||||||
|
REQUIRE(g["Suffix"].parse("aaa? ") == true);
|
||||||
|
REQUIRE(g["Suffix"].parse("aaa* ") == true);
|
||||||
|
REQUIRE(g["Suffix"].parse("aaa+ ") == true);
|
||||||
|
REQUIRE(g["Suffix"].parse(". + ") == true);
|
||||||
|
REQUIRE(g["Suffix"].parse("?") == false);
|
||||||
|
REQUIRE(g["Suffix"].parse("") == false);
|
||||||
|
REQUIRE(g["Sequence"].parse(" a") == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("PEG Primary", "[peg]")
|
||||||
|
{
|
||||||
|
Grammar g = make_peg_grammar();
|
||||||
|
REQUIRE(g["Primary"].parse("_Identifier0_ ") == true);
|
||||||
|
REQUIRE(g["Primary"].parse("_Identifier0_<-") == false);
|
||||||
|
REQUIRE(g["Primary"].parse("( _Identifier0_ _Identifier1_ )") == true);
|
||||||
|
REQUIRE(g["Primary"].parse("'Literal String'") == true);
|
||||||
|
REQUIRE(g["Primary"].parse("\"Literal String\"") == true);
|
||||||
|
REQUIRE(g["Primary"].parse("[a-zA-Z]") == true);
|
||||||
|
REQUIRE(g["Primary"].parse(".") == true);
|
||||||
|
REQUIRE(g["Primary"].parse("") == false);
|
||||||
|
REQUIRE(g["Primary"].parse(" ") == false);
|
||||||
|
REQUIRE(g["Primary"].parse(" a") == false);
|
||||||
|
REQUIRE(g["Primary"].parse("") == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("PEG Identifier", "[peg]")
|
||||||
|
{
|
||||||
|
Grammar g = make_peg_grammar();
|
||||||
|
REQUIRE(g["Identifier"].parse("_Identifier0_ ") == true);
|
||||||
|
REQUIRE(g["Identifier"].parse("0Identifier_ ") == false);
|
||||||
|
REQUIRE(g["Identifier"].parse("Iden|t ") == false);
|
||||||
|
REQUIRE(g["Identifier"].parse(" ") == false);
|
||||||
|
REQUIRE(g["Identifier"].parse(" a") == false);
|
||||||
|
REQUIRE(g["Identifier"].parse("") == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("PEG IdentStart", "[peg]")
|
||||||
|
{
|
||||||
|
Grammar g = make_peg_grammar();
|
||||||
|
REQUIRE(g["IdentStart"].parse("_") == true);
|
||||||
|
REQUIRE(g["IdentStart"].parse("a") == true);
|
||||||
|
REQUIRE(g["IdentStart"].parse("Z") == true);
|
||||||
|
REQUIRE(g["IdentStart"].parse("") == false);
|
||||||
|
REQUIRE(g["IdentStart"].parse(" ") == false);
|
||||||
|
REQUIRE(g["IdentStart"].parse("0") == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("PEG IdentCont", "[peg]")
|
||||||
|
{
|
||||||
|
Grammar g = make_peg_grammar();
|
||||||
|
REQUIRE(g["IdentCont"].parse("_") == true);
|
||||||
|
REQUIRE(g["IdentCont"].parse("a") == true);
|
||||||
|
REQUIRE(g["IdentCont"].parse("Z") == true);
|
||||||
|
REQUIRE(g["IdentCont"].parse("") == false);
|
||||||
|
REQUIRE(g["IdentCont"].parse(" ") == false);
|
||||||
|
REQUIRE(g["IdentCont"].parse("0") == true);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("PEG Literal", "[peg]")
|
||||||
|
{
|
||||||
|
Grammar g = make_peg_grammar();
|
||||||
|
REQUIRE(g["Literal"].parse("'abc' ") == true);
|
||||||
|
REQUIRE(g["Literal"].parse("'a\\nb\\tc' ") == true);
|
||||||
|
REQUIRE(g["Literal"].parse("'a\\277\tc' ") == true);
|
||||||
|
REQUIRE(g["Literal"].parse("'a\\77\tc' ") == true);
|
||||||
|
REQUIRE(g["Literal"].parse("'a\\80\tc' ") == false);
|
||||||
|
REQUIRE(g["Literal"].parse("'\n' ") == true);
|
||||||
|
REQUIRE(g["Literal"].parse("'a\\'b' ") == true);
|
||||||
|
REQUIRE(g["Literal"].parse("'a'b' ") == false);
|
||||||
|
REQUIRE(g["Literal"].parse("'a\"'b' ") == false);
|
||||||
|
REQUIRE(g["Literal"].parse("\"'\\\"abc\\\"'\" ") == true);
|
||||||
|
REQUIRE(g["Literal"].parse("\"'\"abc\"'\" ") == false);
|
||||||
|
REQUIRE(g["Literal"].parse("abc") == false);
|
||||||
|
REQUIRE(g["Literal"].parse("") == false);
|
||||||
|
REQUIRE(g["Literal"].parse("日本語") == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("PEG Class", "[peg]")
|
||||||
|
{
|
||||||
|
Grammar g = make_peg_grammar();
|
||||||
|
REQUIRE(g["Class"].parse("[]") == true);
|
||||||
|
REQUIRE(g["Class"].parse("[a]") == true);
|
||||||
|
REQUIRE(g["Class"].parse("[a-z]") == true);
|
||||||
|
REQUIRE(g["Class"].parse("[az]") == true);
|
||||||
|
REQUIRE(g["Class"].parse("[a-zA-Z-]") == true);
|
||||||
|
REQUIRE(g["Class"].parse("[a-zA-Z-0-9]") == true);
|
||||||
|
REQUIRE(g["Class"].parse("[a-]") == false);
|
||||||
|
REQUIRE(g["Class"].parse("[-a]") == true);
|
||||||
|
REQUIRE(g["Class"].parse("[") == false);
|
||||||
|
REQUIRE(g["Class"].parse("[a") == false);
|
||||||
|
REQUIRE(g["Class"].parse("]") == false);
|
||||||
|
REQUIRE(g["Class"].parse("a]") == false);
|
||||||
|
REQUIRE(g["Class"].parse("あ-ん") == false);
|
||||||
|
REQUIRE(g["Class"].parse("[-+]") == true);
|
||||||
|
REQUIRE(g["Class"].parse("[+-]") == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("PEG Range", "[peg]")
|
||||||
|
{
|
||||||
|
Grammar g = make_peg_grammar();
|
||||||
|
REQUIRE(g["Range"].parse("a") == true);
|
||||||
|
REQUIRE(g["Range"].parse("a-z") == true);
|
||||||
|
REQUIRE(g["Range"].parse("az") == false);
|
||||||
|
REQUIRE(g["Range"].parse("") == false);
|
||||||
|
REQUIRE(g["Range"].parse("a-") == false);
|
||||||
|
REQUIRE(g["Range"].parse("-a") == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("PEG Char", "[peg]")
|
||||||
|
{
|
||||||
|
Grammar g = make_peg_grammar();
|
||||||
|
REQUIRE(g["Char"].parse("\\n") == true);
|
||||||
|
REQUIRE(g["Char"].parse("\\r") == true);
|
||||||
|
REQUIRE(g["Char"].parse("\\t") == true);
|
||||||
|
REQUIRE(g["Char"].parse("\\'") == true);
|
||||||
|
REQUIRE(g["Char"].parse("\\\"") == true);
|
||||||
|
REQUIRE(g["Char"].parse("\\[") == true);
|
||||||
|
REQUIRE(g["Char"].parse("\\]") == true);
|
||||||
|
REQUIRE(g["Char"].parse("\\\\") == true);
|
||||||
|
REQUIRE(g["Char"].parse("\\000") == true);
|
||||||
|
REQUIRE(g["Char"].parse("\\277") == true);
|
||||||
|
REQUIRE(g["Char"].parse("\\377") == false);
|
||||||
|
REQUIRE(g["Char"].parse("\\087") == false);
|
||||||
|
REQUIRE(g["Char"].parse("\\079") == false);
|
||||||
|
REQUIRE(g["Char"].parse("\\00") == true);
|
||||||
|
REQUIRE(g["Char"].parse("\\77") == true);
|
||||||
|
REQUIRE(g["Char"].parse("\\80") == false);
|
||||||
|
REQUIRE(g["Char"].parse("\\08") == false);
|
||||||
|
REQUIRE(g["Char"].parse("\\0") == true);
|
||||||
|
REQUIRE(g["Char"].parse("\\7") == true);
|
||||||
|
REQUIRE(g["Char"].parse("\\8") == false);
|
||||||
|
REQUIRE(g["Char"].parse("a") == true);
|
||||||
|
REQUIRE(g["Char"].parse(".") == true);
|
||||||
|
REQUIRE(g["Char"].parse("0") == true);
|
||||||
|
REQUIRE(g["Char"].parse("\\") == false);
|
||||||
|
REQUIRE(g["Char"].parse(" ") == true);
|
||||||
|
REQUIRE(g["Char"].parse(" ") == false);
|
||||||
|
REQUIRE(g["Char"].parse("") == false);
|
||||||
|
REQUIRE(g["Char"].parse("あ") == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("PEG Operators", "[peg]")
|
||||||
|
{
|
||||||
|
Grammar g = make_peg_grammar();
|
||||||
|
REQUIRE(g["LEFTARROW"].parse("<-") == true);
|
||||||
|
REQUIRE(g["SLASH"].parse("/ ") == true);
|
||||||
|
REQUIRE(g["AND"].parse("& ") == true);
|
||||||
|
REQUIRE(g["NOT"].parse("! ") == true);
|
||||||
|
REQUIRE(g["QUESTION"].parse("? ") == true);
|
||||||
|
REQUIRE(g["STAR"].parse("* ") == true);
|
||||||
|
REQUIRE(g["PLUS"].parse("+ ") == true);
|
||||||
|
REQUIRE(g["OPEN"].parse("( ") == true);
|
||||||
|
REQUIRE(g["CLOSE"].parse(") ") == true);
|
||||||
|
REQUIRE(g["DOT"].parse(". ") == true);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("PEG Comment", "[peg]")
|
||||||
|
{
|
||||||
|
Grammar g = make_peg_grammar();
|
||||||
|
REQUIRE(g["Comment"].parse("# Comment.\n") == true);
|
||||||
|
REQUIRE(g["Comment"].parse("# Comment.") == false);
|
||||||
|
REQUIRE(g["Comment"].parse(" ") == false);
|
||||||
|
REQUIRE(g["Comment"].parse("a") == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("PEG Space", "[peg]")
|
||||||
|
{
|
||||||
|
Grammar g = make_peg_grammar();
|
||||||
|
REQUIRE(g["Space"].parse(" ") == true);
|
||||||
|
REQUIRE(g["Space"].parse("\t") == true);
|
||||||
|
REQUIRE(g["Space"].parse("\n") == true);
|
||||||
|
REQUIRE(g["Space"].parse("") == false);
|
||||||
|
REQUIRE(g["Space"].parse("a") == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("PEG EndOfLine", "[peg]")
|
||||||
|
{
|
||||||
|
Grammar g = make_peg_grammar();
|
||||||
|
REQUIRE(g["EndOfLine"].parse("\r\n") == true);
|
||||||
|
REQUIRE(g["EndOfLine"].parse("\n") == true);
|
||||||
|
REQUIRE(g["EndOfLine"].parse("\r") == true);
|
||||||
|
REQUIRE(g["EndOfLine"].parse(" ") == false);
|
||||||
|
REQUIRE(g["EndOfLine"].parse("") == false);
|
||||||
|
REQUIRE(g["EndOfLine"].parse("a") == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("PEG EndOfFile", "[peg]")
|
||||||
|
{
|
||||||
|
Grammar g = make_peg_grammar();
|
||||||
|
REQUIRE(g["EndOfFile"].parse("") == true);
|
||||||
|
REQUIRE(g["EndOfFile"].parse(" ") == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// vim: et ts=4 sw=4 cin cino={1s ff=unix
|
28
test/test.sln
Normal file
28
test/test.sln
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Express 2013 for Windows Desktop
|
||||||
|
VisualStudioVersion = 12.0.20617.1 PREVIEW
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcxproj", "{6B3E6769-052D-4BC0-9D2C-E9127C3DBB26}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Win32 = Debug|Win32
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Release|Win32 = Release|Win32
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{6B3E6769-052D-4BC0-9D2C-E9127C3DBB26}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{6B3E6769-052D-4BC0-9D2C-E9127C3DBB26}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{6B3E6769-052D-4BC0-9D2C-E9127C3DBB26}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{6B3E6769-052D-4BC0-9D2C-E9127C3DBB26}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{6B3E6769-052D-4BC0-9D2C-E9127C3DBB26}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{6B3E6769-052D-4BC0-9D2C-E9127C3DBB26}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{6B3E6769-052D-4BC0-9D2C-E9127C3DBB26}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{6B3E6769-052D-4BC0-9D2C-E9127C3DBB26}.Release|x64.Build.0 = Release|x64
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
159
test/test.vcxproj
Normal file
159
test/test.vcxproj
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{6B3E6769-052D-4BC0-9D2C-E9127C3DBB26}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<RootNamespace>test</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>./;../</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>./;../</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>./;../</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>./;../</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="test.cc" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\peglib.h" />
|
||||||
|
<ClInclude Include="..\variant.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
Loading…
Reference in New Issue
Block a user