Skip to content

NotArne/cppparser

This branch is 42 commits behind satya-das/cppparser:master.

Folders and files

NameName
Last commit message
Last commit date
Oct 3, 2022
Feb 8, 2014
Oct 3, 2022
Oct 3, 2022
Oct 3, 2022
Nov 20, 2021
Sep 17, 2018
Dec 5, 2021
Oct 23, 2020
Oct 3, 2022
May 6, 2018
Mar 9, 2022

Repository files navigation

CppParser

Build Status Codacy Badge License: MIT

An easy, fast, and robust library to parse C/C++ source.

Features

  • No pre-processing, and preprocessors are part of the ast.
  • Most comments are preserved too.
  • Developed from scratch and uses back-tracking yacc (BtYacc) to write C++ grammer, that means no dependency on libclang.
  • The result of parsing is an AST where elements of a file are arranged in a tree.
  • Minimum dependency. Only external dependency is a lexer which is by default available on unix like platforms and can be easily get on Windows.
  • Parsing of multi-file program is supported too.

Motivation

CppParser can be used to build tools that need parsing of C/C++ files. I am using it to develop cib which implements ABI stable SDK architecture for C++ library.

Example

To begin with we will see an example of parsing a hello-world program and see what is the AST that CppParser creates:

#include <iostream>

int main()
{
  std::cout << "Hello World!\n";

  return 0;
}

For the above hello-world program we can expect that when it is parsed the generated AST should look like following: AST for Hello World program

So, how we are going to access these elements of AST using CppParser? Below is the program written as unit-test for validating the correctness of generated AST:

#include <catch/catch.hpp>

#include "cppparser.h"

#include <boost/filesystem.hpp>

namespace fs = boost::filesystem;

TEST_CASE("Parsing hello world program")
{
  CppParser  parser;
  const auto testFilePath = fs::path(__FILE__).parent_path() / "test-files/hello-world.cpp";
  const auto ast          = parser.parseFile(testFilePath.string());
  REQUIRE(ast != nullptr);

  const auto& members = ast->members();
  REQUIRE(members.size() == 2);

  CppIncludeEPtr hashInclude = members[0];
  REQUIRE(hashInclude);
  CHECK(hashInclude->name_ == "<iostream>");

  CppFunctionEPtr func = members[1];
  REQUIRE(func);
  CHECK(func->name_ == "main");

  REQUIRE(func->defn());
  const auto& mainBodyMembers = func->defn()->members();
  REQUIRE(mainBodyMembers.size() == 2);

  CppExprEPtr coutHelloWorld = mainBodyMembers[0];
  REQUIRE(coutHelloWorld);
  CHECK(coutHelloWorld->oper_ == CppOperator::kInsertion);
}

This example is a real one and is part of actual unit test of CppParser.

Building CppParser

Get the source

git clone https://github.com/satya-das/common.git
git clone https://github.com/satya-das/CppParser.git

Configure and build

cd cppparser
mkdir builds
cd builds
cmake ..
make && make test

Alternatively, if you prefer Ninja instead of make:

cd cppparser
mkdir builds
cd builds
cmake -G Ninja ..
ninja && ninja test

About

A library to parse C/C++ source as AST

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C++ 73.7%
  • Objective-C 18.9%
  • C 7.1%
  • Yacc 0.2%
  • Lex 0.1%
  • CMake 0.0%