Commit 0aa4ec27 authored by Daniel Clifford's avatar Daniel Clifford Committed by Commit Bot

Add antlr4 runtime library to support Torque

Separating from main mega-CL for Torque to make landing it more
manageable.

Change-Id: Ic2cf2f5bff62613cb25cddd065479c85cfd9dd6c
Reviewed-on: https://chromium-review.googlesource.com/963704Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Daniel Clifford <danno@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52514}
parent 1e928e90
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
/test/wasm-spec-tests/tests /test/wasm-spec-tests/tests
/test/wasm-spec-tests/tests.tar.gz /test/wasm-spec-tests/tests.tar.gz
/third_party/* /third_party/*
!/third_party/antlr4
!/third_party/binutils !/third_party/binutils
!/third_party/eu-strip !/third_party/eu-strip
!/third_party/inspector_protocol !/third_party/inspector_protocol
......
...@@ -23,6 +23,9 @@ are: ...@@ -23,6 +23,9 @@ are:
- Valgrind client API header, located at third_party/valgrind/valgrind.h - Valgrind client API header, located at third_party/valgrind/valgrind.h
This is release under the BSD license. This is release under the BSD license.
- antlr4 parser generator Cpp library located in third_party/antlr4
This is release under the BSD license.
These libraries have their own licenses; we recommend you read them, These libraries have their own licenses; we recommend you read them,
as their terms may differ from the terms below. as their terms may differ from the terms below.
......
[The "BSD 3-clause license"]
Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=====
MIT License for codepointat.js from https://git.io/codepointat
MIT License for fromcodepoint.js from https://git.io/vDW1m
Copyright Mathias Bynens <https://mathiasbynens.be/>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# -*- mode:cmake -*-
cmake_minimum_required (VERSION 2.8)
# 2.8 needed because of ExternalProject
# Detect build type, fallback to release and throw a warning if use didn't specify any
if(NOT CMAKE_BUILD_TYPE)
message(WARNING "Build type not set, falling back to Release mode.
To specify build type use:
-DCMAKE_BUILD_TYPE=<mode> where <mode> is Debug or Release.")
set(CMAKE_BUILD_TYPE "Release" CACHE STRING
"Choose the type of build, options are: Debug Release."
FORCE)
endif(NOT CMAKE_BUILD_TYPE)
if(NOT WITH_DEMO)
message(STATUS "Building without demo. To enable demo build use: -DWITH_DEMO=True")
set(WITH_DEMO False CACHE STRING
"Chose to build with or without demo executable"
FORCE)
endif(NOT WITH_DEMO)
option(WITH_LIBCXX "Building with clang++ and libc++(in Linux). To enable with: -DWITH_LIBCXX=On" On)
project(LIBANTLR4)
if(CMAKE_VERSION VERSION_EQUAL "3.0.0" OR
CMAKE_VERSION VERSION_GREATER "3.0.0")
CMAKE_POLICY(SET CMP0026 NEW)
CMAKE_POLICY(SET CMP0054 OLD)
CMAKE_POLICY(SET CMP0045 OLD)
CMAKE_POLICY(SET CMP0042 OLD)
endif()
if(CMAKE_VERSION VERSION_EQUAL "3.3.0" OR
CMAKE_VERSION VERSION_GREATER "3.3.0")
CMAKE_POLICY(SET CMP0059 OLD)
CMAKE_POLICY(SET CMP0054 OLD)
endif()
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
find_package(PkgConfig REQUIRED)
pkg_check_modules(UUID REQUIRED uuid)
endif()
if(APPLE)
find_library(COREFOUNDATION_LIBRARY CoreFoundation)
endif()
file(STRINGS "VERSION" ANTLR_VERSION)
if (WITH_DEMO)
# Java is not necessary if building without demos.
find_package(Java COMPONENTS Runtime REQUIRED)
if (NOT ANTLR_JAR_LOCATION)
message(FATAL_ERROR "Missing antlr4.jar location. You can specify it's path using: -DANTLR_JAR_LOCATION=<path>")
else()
get_filename_component(ANTLR_NAME ${ANTLR_JAR_LOCATION} NAME_WE)
if(NOT EXISTS "${ANTLR_JAR_LOCATION}")
message(FATAL_ERROR "Unable to find ${ANTLR_NAME} in ${ANTLR_JAR_LOCATION}")
else()
message(STATUS "Found ${ANTLR_NAME}: ${ANTLR_JAR_LOCATION}")
endif()
endif()
endif(WITH_DEMO)
if (MSVC_VERSION)
set(MY_CXX_WARNING_FLAGS " /W4")
else()
set(MY_CXX_WARNING_FLAGS " -Wall -pedantic -W")
endif()
# Initialize CXXFLAGS.
if("${CMAKE_VERSION}" VERSION_GREATER 3.1.0)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11")
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -std=c++11")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -std=c++11")
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MY_CXX_WARNING_FLAGS}")
if (MSVC_VERSION)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /Zi /MP ${MY_CXX_WARNING_FLAGS}")
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} /O1 /Oi /Ob2 /Gy /MP /DNDEBUG ${MY_CXX_WARNING_FLAGS}")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /O2 /Oi /Ob2 /Gy /MP /DNDEBUG ${MY_CXX_WARNING_FLGAS}")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /O2 /Oi /Ob2 /Gy /MP /Zi ${MY_CXX_WARNING_FLAGS}")
else()
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -g ${MY_CXX_WARNING_FLAGS}")
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -Os -DNDEBUG ${MY_CXX_WARNING_FLAGS}")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -DNDEBUG ${MY_CXX_WARNING_FLGAS}")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O2 -g ${MY_CXX_WARNING_FLAGS}")
endif()
# Compiler-specific C++11 activation.
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Intel")
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
# Just g++-5.0 and greater contain <codecvt> header. (test in ubuntu)
if (NOT (GCC_VERSION VERSION_GREATER 5.0 OR GCC_VERSION VERSION_EQUAL 5.0))
message(FATAL_ERROR "${PROJECT_NAME} requires g++ 5.0 or greater.")
endif ()
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND CMAKE_SYSTEM_NAME MATCHES "Linux")
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE CLANG_VERSION)
if (NOT (CLANG_VERSION VERSION_GREATER 4.2.1 OR CLANG_VERSION VERSION_EQUAL 4.2.1))
message(FATAL_ERROR "${PROJECT_NAME} requires clang 4.2.1 or greater.")
endif ()
# You can use libc++ to compile this project when g++ is NOT greater than or equal to 5.0.
if (WITH_LIBCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
endif()
elseif ( MSVC_VERSION GREATER 1800 OR MSVC_VERSION EQUAL 1800 )
# Visual Studio 2012+ supports c++11 features
else ()
message(FATAL_ERROR "Your C++ compiler does not support C++11.")
endif ()
add_subdirectory(runtime)
if (WITH_DEMO)
add_subdirectory(demo)
endif(WITH_DEMO)
if( EXISTS LICENSE.txt)
install(FILES LICENSE.txt
DESTINATION "share/doc/libantlr4")
elseif(EXISTS ../../LICENSE.txt)
install(FILES ../../LICENSE.txt
DESTINATION "share/doc/libantlr4")
endif()
install(FILES README.md VERSION
DESTINATION "share/doc/libantlr4")
# C++ target for ANTLR 4
This folder contains the C++ runtime support for ANTLR. See [the canonical antlr4 repository](https://github.com/antlr/antlr4) for in depth detail about how to use ANTLR 4.
## Authors and major contributors
ANTLR 4 is the result of substantial effort of the following people:
* [Terence Parr](http://www.cs.usfca.edu/~parrt/), parrt@cs.usfca.edu
ANTLR project lead and supreme dictator for life
[University of San Francisco](http://www.usfca.edu/)
* [Sam Harwell](http://tunnelvisionlabs.com/)
Tool co-author, Java and C# target)
The C++ target has been the work of the following people:
* Dan McLaughlin, dan.mclaughlin@gmail.com (initial port, got code to compile)
* David Sisson, dsisson@google.com (initial port, made the runtime C++ tests runnable)
* [Mike Lischke](www.soft-gems.net), mike@lischke-online.de (brought the initial port to a working library, made most runtime tests passing)
## Other contributors
* Marcin Szalowicz, mszalowicz@mailplus.pl (cmake build setup)
* Tim O'Callaghan, timo@linux.com (additional superbuild cmake pattern script)
## Project Status
* Building on OS X, Windows, and Linux
* No errors and warnings
* Library linking
* Some unit tests in the OSX project, for important base classes with almost 100% code coverage.
* All memory allocations checked
* Simple command line demo application working on all supported platforms.
* All runtime tests pass.
### Build + Usage Notes
The minimum C++ version to compile the ANTLR C++ runtime with is C++11. The supplied projects can built the runtime either as static or dynamic library, as both 32bit and 64bit arch. The OSX project contains a target for iOS and can also be built using cmake (instead of XCode).
Include the antlr4-runtime.h umbrella header in your target application to get everything needed to use the library.
If you are compiling with cmake, the minimum version required is cmake 2.8.
#### Compiling on Windows
Simply open the VS solution (VS 2013+) and build it.
#### Compiling on OSX
Either open the included XCode project and build that or use the cmake compilation as described for linux.
#### Compiling on Linux
- cd <antlr4-dir>/runtime/Cpp (this is where this readme is located)
- mkdir build && mkdir run && cd build
- cmake .. -DANTLR_JAR_LOCATION=full/path/to/antlr4-4.5.4-SNAPSHOT.jar -DWITH_DEMO=True
- make
- DESTDIR=<antlr4-dir>/runtime/Cpp/run make install
If you don't want to build the demo then simply run cmake without parameters.
There is another cmake script available in the subfolder cmake/ for those who prefer the superbuild cmake pattern.
# -*- mode:cmake -*-
#
# This Cmake file is for those using a superbuild Cmake Pattern, it
# will download the tools and build locally
#
# use 2the antlr4cpp_process_grammar to support multiple grammars in the
# same project
#
# - Getting quicky started with Antlr4cpp
#
# Here is how you can use this external project to create the antlr4cpp
# demo to start your project off.
#
# create your project source folder somewhere. e.g. ~/srcfolder/
# + make a subfolder cmake
# + Copy this file to srcfolder/cmake
# + cut below and use it to create srcfolder/CMakeLists.txt,
# + from https://github.com/DanMcLaughlin/antlr4/tree/master/runtime/Cpp/demo Copy main.cpp, TLexer.g4 and TParser.g4 to ./srcfolder/
#
# next make a build folder e.g. ~/buildfolder/
# from the buildfolder, run cmake ~/srcfolder; make
#
###############################################################
# # minimum required CMAKE version
# CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12.2 FATAL_ERROR)
#
# LIST( APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake )
#
# # compiler must be 11 or 14
# SET (CMAKE_CXX_STANDARD 11)
#
# # set variable pointing to the antlr tool that supports C++
# set(ANTLR4CPP_JAR_LOCATION /home/user/antlr4-4.5.4-SNAPSHOT.jar)
# # add external build for antlrcpp
# include( ExternalAntlr4Cpp )
# # add antrl4cpp artifacts to project environment
# include_directories( ${ANTLR4CPP_INCLUDE_DIRS} )
# link_directories( ${ANTLR4CPP_LIBS} )
# message(STATUS "Found antlr4cpp libs: ${ANTLR4CPP_LIBS} and includes: ${ANTLR4CPP_INCLUDE_DIRS} ")
#
# # Call macro to add lexer and grammar to your build dependencies.
# antlr4cpp_process_grammar(demo antlrcpptest
# ${CMAKE_CURRENT_SOURCE_DIR}/TLexer.g4
# ${CMAKE_CURRENT_SOURCE_DIR}/TParser.g4)
# # include generated files in project environment
# include_directories(${antlr4cpp_include_dirs_antlrcpptest})
#
# # add generated grammar to demo binary target
# add_executable(demo main.cpp ${antlr4cpp_src_files_antlrcpptest})
# add_dependencies(demo antlr4cpp antlr4cpp_generation_antlrcpptest)
# target_link_libraries(demo antlr4-runtime)
#
###############################################################
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12.2)
PROJECT(antlr4cpp_fetcher CXX)
INCLUDE(ExternalProject)
FIND_PACKAGE(Git REQUIRED)
# only JRE required
FIND_PACKAGE(Java COMPONENTS Runtime REQUIRED)
############ Download and Generate runtime #################
set(ANTLR4CPP_EXTERNAL_ROOT ${CMAKE_BINARY_DIR}/externals/antlr4cpp)
# external repository
# GIT_REPOSITORY https://github.com/antlr/antlr4.git
set(ANTLR4CPP_EXTERNAL_REPO "https://github.com/antlr/antlr4.git")
set(ANTLR4CPP_EXTERNAL_TAG "4.7.1")
if(NOT EXISTS "${ANTLR4CPP_JAR_LOCATION}")
message(FATAL_ERROR "Unable to find antlr tool. ANTLR4CPP_JAR_LOCATION:${ANTLR4CPP_JAR_LOCATION}")
endif()
# default path for source files
if (NOT ANTLR4CPP_GENERATED_SRC_DIR)
set(ANTLR4CPP_GENERATED_SRC_DIR ${CMAKE_BINARY_DIR}/antlr4cpp_generated_src)
endif()
# !TODO! This should probably check with Cmake Find first?
# set(ANTLR4CPP_JAR_LOCATION ${ANTLR4CPP_EXTERNAL_ROOT}/${ANTLR4CPP_JAR_NAME})
#
# !TODO! Ensure Antlr tool available - copy from internet
#
# # !TODO! this shold be calculated based on the tags
# if (NOT ANTLR4CPP_JAR_NAME)
# # default location to find antlr Java binary
# set(ANTLR4CPP_JAR_NAME antlr4-4.5.4-SNAPSHOT.jar)
# endif()
#
# if(NOT EXISTS "${ANTLR4CPP_JAR_LOCATION}")
# # download Java tool if not installed
# ExternalProject_ADD(
# #--External-project-name------
# antlrtool
# #--Core-directories-----------
# PREFIX ${ANTLR4CPP_EXTERNAL_ROOT}
# #--Download step--------------
# DOWNLOAD_DIR ${ANTLR4CPP_EXTERNAL_ROOT}
# DOWNLOAD_COMMAND ""
# # URL http://www.antlr.org/download/${ANTLR4CPP_JAR_NAME}
# # antlr4-4.5.4-SNAPSHOT.jar
# # GIT_TAG v4.5.4
# TIMEOUT 10
# LOG_DOWNLOAD ON
# #--Update step----------
# # UPDATE_COMMAND ${GIT_EXECUTABLE} pull
# #--Patch step----------
# # PATCH_COMMAND sh -c "cp <SOURCE_DIR>/scripts/CMakeLists.txt <SOURCE_DIR>"
# #--Configure step-------------
# CMAKE_ARGS ""
# CONFIGURE_COMMAND ""
# LOG_CONFIGURE ON
# #--Build step-----------------
# BUILD_COMMAND ""
# LOG_BUILD ON
# #--Install step---------------
# INSTALL_COMMAND ""
# )
# # Verify Antlr Available
# if(NOT EXISTS "${ANTLR4CPP_JAR_LOCATION}")
# message(FATAL_ERROR "Unable to find ANTLR4CPP_JAR_LOCATION:${ANTLR4CPP_JAR_LOCATION} -> ${ANTLR4CPP_JAR_NAME} not in ${ANTLR4CPP_DIR} ")
# endif()
# endif()
# download runtime environment
ExternalProject_ADD(
#--External-project-name------
antlr4cpp
#--Depend-on-antrl-tool-----------
# DEPENDS antlrtool
#--Core-directories-----------
PREFIX ${ANTLR4CPP_EXTERNAL_ROOT}
#--Download step--------------
GIT_REPOSITORY ${ANTLR4CPP_EXTERNAL_REPO}
# GIT_TAG ${ANTLR4CPP_EXTERNAL_TAG}
TIMEOUT 10
LOG_DOWNLOAD ON
#--Update step----------
UPDATE_COMMAND ${GIT_EXECUTABLE} pull
#--Patch step----------
# PATCH_COMMAND sh -c "cp <SOURCE_DIR>/scripts/CMakeLists.txt <SOURCE_DIR>"
#--Configure step-------------
CONFIGURE_COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Release -DANTLR4CPP_JAR_LOCATION=${ANTLR4CPP_JAR_LOCATION} -DBUILD_SHARED_LIBS=ON -BUILD_TESTS=OFF -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_SOURCE_DIR:PATH=<SOURCE_DIR>/runtime/Cpp <SOURCE_DIR>/runtime/Cpp
LOG_CONFIGURE ON
#--Build step-----------------
# BUILD_COMMAND ${CMAKE_MAKE_PROGRAM}
LOG_BUILD ON
#--Install step---------------
# INSTALL_COMMAND ""
# INSTALL_DIR ${CMAKE_BINARY_DIR}/
#--Install step---------------
# INSTALL_COMMAND ""
)
ExternalProject_Get_Property(antlr4cpp INSTALL_DIR)
list(APPEND ANTLR4CPP_INCLUDE_DIRS ${INSTALL_DIR}/include/antlr4-runtime)
foreach(src_path misc atn dfa tree support)
list(APPEND ANTLR4CPP_INCLUDE_DIRS ${INSTALL_DIR}/include/antlr4-runtime/${src_path})
endforeach(src_path)
set(ANTLR4CPP_LIBS "${INSTALL_DIR}/lib")
# antlr4_shared ${INSTALL_DIR}/lib/libantlr4-runtime.so
# antlr4_static ${INSTALL_DIR}/lib/libantlr4-runtime.a
############ Generate runtime #################
# macro to add dependencies to target
#
# Param 1 project name
# Param 1 namespace (postfix for dependencies)
# Param 2 Lexer file (full path)
# Param 3 Parser File (full path)
#
# output
#
# antlr4cpp_src_files_{namespace} - src files for add_executable
# antlr4cpp_include_dirs_{namespace} - include dir for generated headers
# antlr4cpp_generation_{namespace} - for add_dependencies tracking
macro(antlr4cpp_process_grammar
antlr4cpp_project
antlr4cpp_project_namespace
antlr4cpp_grammar_lexer
antlr4cpp_grammar_parser)
if(EXISTS "${ANTLR4CPP_JAR_LOCATION}")
message(STATUS "Found antlr tool: ${ANTLR4CPP_JAR_LOCATION}")
else()
message(FATAL_ERROR "Unable to find antlr tool. ANTLR4CPP_JAR_LOCATION:${ANTLR4CPP_JAR_LOCATION}")
endif()
add_custom_target("antlr4cpp_generation_${antlr4cpp_project_namespace}"
COMMAND
${CMAKE_COMMAND} -E make_directory ${ANTLR4CPP_GENERATED_SRC_DIR}
COMMAND
"${Java_JAVA_EXECUTABLE}" -jar "${ANTLR4CPP_JAR_LOCATION}" -Werror -Dlanguage=Cpp -listener -visitor -o "${ANTLR4CPP_GENERATED_SRC_DIR}/${antlr4cpp_project_namespace}" -package ${antlr4cpp_project_namespace} "${antlr4cpp_grammar_lexer}" "${antlr4cpp_grammar_parser}"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
DEPENDS "${antlr4cpp_grammar_lexer}" "${antlr4cpp_grammar_parser}"
)
# Find all the input files
FILE(GLOB generated_files ${ANTLR4CPP_GENERATED_SRC_DIR}/${antlr4cpp_project_namespace}/*.cpp)
# export generated cpp files into list
foreach(generated_file ${generated_files})
list(APPEND antlr4cpp_src_files_${antlr4cpp_project_namespace} ${generated_file})
if (NOT CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
set_source_files_properties(
${generated_file}
PROPERTIES
COMPILE_FLAGS -Wno-overloaded-virtual
)
endif ()
endforeach(generated_file)
message(STATUS "Antlr4Cpp ${antlr4cpp_project_namespace} Generated: ${generated_files}")
# export generated include directory
set(antlr4cpp_include_dirs_${antlr4cpp_project_namespace} ${ANTLR4CPP_GENERATED_SRC_DIR}/${antlr4cpp_project_namespace})
message(STATUS "Antlr4Cpp ${antlr4cpp_project_namespace} include: ${ANTLR4CPP_GENERATED_SRC_DIR}/${antlr4cpp_project_namespace}")
endmacro()
# -*- mode:cmake -*-
if(NOT UNIX)
message(WARNING "Unsupported operating system")
endif()
set(antlr4-demo-GENERATED_SRC
${PROJECT_SOURCE_DIR}/demo/generated/TLexer.cpp
${PROJECT_SOURCE_DIR}/demo/generated/TParser.cpp
${PROJECT_SOURCE_DIR}/demo/generated/TParserBaseListener.cpp
${PROJECT_SOURCE_DIR}/demo/generated/TParserBaseVisitor.cpp
${PROJECT_SOURCE_DIR}/demo/generated/TParserListener.cpp
${PROJECT_SOURCE_DIR}/demo/generated/TParserVisitor.cpp
)
foreach( src_file ${antlr4-demo-GENERATED_SRC} )
set_source_files_properties(
${src_file}
PROPERTIES
GENERATED TRUE
)
endforeach( src_file ${antlr4-demo-GENERATED_SRC} )
add_custom_target(GenerateParser DEPENDS ${antlr4-demo-GENERATED_SRC})
add_custom_command(OUTPUT ${antlr4-demo-GENERATED_SRC}
COMMAND
${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/demo/generated/
COMMAND
"${Java_JAVA_EXECUTABLE}" -jar ${ANTLR_JAR_LOCATION} -Werror -Dlanguage=Cpp -listener -visitor -o ${PROJECT_SOURCE_DIR}/demo/generated/ -package antlrcpptest ${PROJECT_SOURCE_DIR}/demo/TLexer.g4 ${PROJECT_SOURCE_DIR}/demo/TParser.g4
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
DEPENDS ${PROJECT_SOURCE_DIR}/demo/TLexer.g4 ${PROJECT_SOURCE_DIR}/demo/TParser.g4
)
include_directories(
${PROJECT_SOURCE_DIR}/runtime/src
${PROJECT_SOURCE_DIR}/runtime/src/misc
${PROJECT_SOURCE_DIR}/runtime/src/atn
${PROJECT_SOURCE_DIR}/runtime/src/dfa
${PROJECT_SOURCE_DIR}/runtime/src/tree
${PROJECT_SOURCE_DIR}/runtime/src/support
${PROJECT_SOURCE_DIR}/demo/generated
)
#file(GLOB antlr4-demo_SRC "${PROJECT_SOURCE_DIR}/demo/generated/*")
set(antlr4-demo_SRC
${PROJECT_SOURCE_DIR}/demo/Linux/main.cpp
${antlr4-demo-GENERATED_SRC}
)
if (NOT CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
set (flags_1 "-Wno-overloaded-virtual")
else()
set (flags_1 "-MP /wd4251")
endif()
foreach( src_file ${antlr4-demo_SRC} )
set_source_files_properties(
${src_file}
PROPERTIES
COMPILE_FLAGS "${COMPILE_FLAGS} ${flags_1}"
)
endforeach( src_file ${antlr4-demo_SRC} )
add_executable(antlr4-demo
${antlr4-demo_SRC}
)
#add_precompiled_header(antlr4-demo ${PROJECT_SOURCE_DIR}/runtime/src/antlrcpp-Prefix.h)
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
target_compile_options(antlr4-demo PRIVATE "/MT$<$<CONFIG:Debug>:d>")
endif()
add_dependencies(antlr4-demo GenerateParser)
target_link_libraries(antlr4-demo antlr4_static)
install(TARGETS antlr4-demo
DESTINATION "share"
COMPONENT dev
)
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
//
// main.cpp
// antlr4-cpp-demo
//
// Created by Mike Lischke on 13.03.16.
//
#include <iostream>
#include "TLexer.h"
#include "TParser.h"
#include "antlr4-runtime.h"
using namespace antlrcpptest;
using namespace antlr4;
int main(int, const char**) {
ANTLRInputStream input(
u8"🍴 = 🍐 + \"😎\";(((x * π))) * µ + ∰; a + (x * (y ? 0 : 1) + z);");
TLexer lexer(&input);
CommonTokenStream tokens(&lexer);
tokens.fill();
for (auto token : tokens.getTokens()) {
std::cout << token->toString() << std::endl;
}
TParser parser(&tokens);
tree::ParseTree* tree = parser.main();
std::cout << tree->toStringTree(&parser) << std::endl << std::endl;
return 0;
}
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
//
// main.cpp
// antlr4-cpp-demo
//
// Created by Mike Lischke on 13.03.16.
//
#include <iostream>
#include "TLexer.h"
#include "TParser.h"
#include "antlr4-runtime.h"
using namespace antlrcpptest;
using namespace antlr4;
int main(int, const char**) {
ANTLRInputStream input(
u8"🍴 = 🍐 + \"😎\";(((x * π))) * µ + ∰; a + (x * (y ? 0 : 1) + z);");
TLexer lexer(&input);
CommonTokenStream tokens(&lexer);
tokens.fill();
for (auto token : tokens.getTokens()) {
std::cout << token->toString() << std::endl;
}
TParser parser(&tokens);
tree::ParseTree* tree = parser.main();
std::cout << tree->toStringTree(&parser) << std::endl;
return 0;
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
This diff is collapsed.
#!/bin/sh
# [The "BSD license"]
# Copyright (c) 2013 Terence Parr
# Copyright (c) 2013 Dan McLaughlin
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
CURRENT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
ANTLRCPP_XCODEPROJ="${CURRENT_DIR}/antlrcpp.xcodeproj"
# OS X
xcrun xcodebuild -project ${ANTLRCPP_XCODEPROJ} -target antlrcpp -configuration Release $@
xcrun xcodebuild -project ${ANTLRCPP_XCODEPROJ} -target antlrcpp -configuration Debug $@
# iOS
#xcrun xcodebuild -project ${ANTLRCPP_XCODEPROJ} -target antlrcpp_iphone -configuration Release -sdk iphoneos $@
#xcrun xcodebuild -project ${ANTLRCPP_XCODEPROJ} -target antlrcpp_iphone -configuration Debug -sdk iphoneos $@
#xcrun xcodebuild -project ${ANTLRCPP_XCODEPROJ} -target antlrcpp_iphone_sim -configuration Release -sdk iphonesimulator $@
#xcrun xcodebuild -project ${ANTLRCPP_XCODEPROJ} -target antlrcpp_iphone_sim -configuration Debug -sdk iphonesimulator $@
## Demo application for the ANTLR 4 C++ target
This demo app shows how to build the ANTLR runtime both as dynamic and static library and how to use a parser generated from a simple demo grammar.
A few steps are necessary to get this to work:
- Download the current ANTLR jar and place it in this folder.
- Open the generation script for your platform (generate.cmd for Windows, generate.sh for *nix/OSX) and update the LOCATION var to the actual name of the jar you downloaded.
- Run the generation script. This will generate a test parser + lexer, along with listener + visitor classes in a subfolder named "generated". This is where the demo application looks for these files.
- Open the project in the folder that matches your system.
- Compile and run.
Compilation is done as described in the [runtime/cpp/readme.md](../README.md) file.
lexer grammar TLexer;
// These are all supported lexer sections:
// Lexer file header. Appears at the top of h + cpp files. Use e.g. for copyrights.
@lexer::header {/* lexer header section */}
// Appears before any #include in h + cpp files.
@lexer::preinclude {/* lexer precinclude section */}
// Follows directly after the standard #includes in h + cpp files.
@lexer::postinclude {
/* lexer postinclude section */
#ifndef _WIN32
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif
}
// Directly preceds the lexer class declaration in the h file (e.g. for additional types etc.).
@lexer::context {/* lexer context section */}
// Appears in the public part of the lexer in the h file.
@lexer::members {/* public lexer declarations section */
bool canTestFoo() { return true; }
bool isItFoo() { return true; }
bool isItBar() { return true; }
void myFooLexerAction() { /* do something*/ };
void myBarLexerAction() { /* do something*/ };
}
// Appears in the private part of the lexer in the h file.
@lexer::declarations {/* private lexer declarations/members section */}
// Appears in line with the other class member definitions in the cpp file.
@lexer::definitions {/* lexer definitions section */}
channels { CommentsChannel, DirectiveChannel }
tokens {
DUMMY
}
Return: 'return';
Continue: 'continue';
INT: Digit+;
Digit: [0-9];
ID: LETTER (LETTER | '0'..'9')*;
fragment LETTER : [a-zA-Z\u0080-\u{10FFFF}];
LessThan: '<';
GreaterThan: '>';
Equal: '=';
And: 'and';
Colon: ':';
Semicolon: ';';
Plus: '+';
Minus: '-';
Star: '*';
OpenPar: '(';
ClosePar: ')';
OpenCurly: '{' -> pushMode(Mode1);
CloseCurly: '}' -> popMode;
QuestionMark: '?';
Comma: ',' -> skip;
Dollar: '$' -> more, mode(Mode1);
Ampersand: '&' -> type(DUMMY);
String: '"' .*? '"';
Foo: {canTestFoo()}? 'foo' {isItFoo()}? { myFooLexerAction(); };
Bar: 'bar' {isItBar()}? { myBarLexerAction(); };
Any: Foo Dot Bar? DotDot Baz;
Comment : '#' ~[\r\n]* '\r'? '\n' -> channel(CommentsChannel);
WS: [ \t\r\n]+ -> channel(99);
fragment Baz: 'Baz';
mode Mode1;
Dot: '.';
mode Mode2;
DotDot: '..';
parser grammar TParser;
options {
tokenVocab = TLexer;
}
// These are all supported parser sections:
// Parser file header. Appears at the top in all parser related files. Use e.g. for copyrights.
@parser::header {/* parser/listener/visitor header section */}
// Appears before any #include in h + cpp files.
@parser::preinclude {/* parser precinclude section */}
// Follows directly after the standard #includes in h + cpp files.
@parser::postinclude {
/* parser postinclude section */
#ifndef _WIN32
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif
}
// Directly preceeds the parser class declaration in the h file (e.g. for additional types etc.).
@parser::context {/* parser context section */}
// Appears in the private part of the parser in the h file.
// The function bodies could also appear in the definitions section, but I want to maximize
// Java compatibility, so we can also create a Java parser from this grammar.
// Still, some tweaking is necessary after the Java file generation (e.g. bool -> boolean).
@parser::members {
/* public parser declarations/members section */
bool myAction() { return true; }
bool doesItBlend() { return true; }
void cleanUp() {}
void doInit() {}
void doAfter() {}
}
// Appears in the public part of the parser in the h file.
@parser::declarations {/* private parser declarations section */}
// Appears in line with the other class member definitions in the cpp file.
@parser::definitions {/* parser definitions section */}
// Additionally there are similar sections for (base)listener and (base)visitor files.
@parser::listenerpreinclude {/* listener preinclude section */}
@parser::listenerpostinclude {/* listener postinclude section */}
@parser::listenerdeclarations {/* listener public declarations/members section */}
@parser::listenermembers {/* listener private declarations/members section */}
@parser::listenerdefinitions {/* listener definitions section */}
@parser::baselistenerpreinclude {/* base listener preinclude section */}
@parser::baselistenerpostinclude {/* base listener postinclude section */}
@parser::baselistenerdeclarations {/* base listener public declarations/members section */}
@parser::baselistenermembers {/* base listener private declarations/members section */}
@parser::baselistenerdefinitions {/* base listener definitions section */}
@parser::visitorpreinclude {/* visitor preinclude section */}
@parser::visitorpostinclude {/* visitor postinclude section */}
@parser::visitordeclarations {/* visitor public declarations/members section */}
@parser::visitormembers {/* visitor private declarations/members section */}
@parser::visitordefinitions {/* visitor definitions section */}
@parser::basevisitorpreinclude {/* base visitor preinclude section */}
@parser::basevisitorpostinclude {/* base visitor postinclude section */}
@parser::basevisitordeclarations {/* base visitor public declarations/members section */}
@parser::basevisitormembers {/* base visitor private declarations/members section */}
@parser::basevisitordefinitions {/* base visitor definitions section */}
// Actual grammar start.
main: stat+ EOF;
divide : ID (and_ GreaterThan)? {doesItBlend()}?;
and_ @init{ doInit(); } @after { doAfter(); } : And ;
conquer:
divide+
| {doesItBlend()}? and_ { myAction(); }
| ID (LessThan* divide)?? { $ID.text; }
;
// Unused rule to demonstrate some of the special features.
unused[double input = 111] returns [double calculated] locals [int _a, double _b, int _c] @init{ doInit(); } @after { doAfter(); } :
stat
;
catch [...] {
// Replaces the standard exception handling.
}
finally {
cleanUp();
}
unused2:
(unused[1] .)+ (Colon | Semicolon | Plus)? ~Semicolon
;
stat: expr Equal expr Semicolon
| expr Semicolon
;
expr: expr Star expr
| expr Plus expr
| OpenPar expr ClosePar
| <assoc = right> expr QuestionMark expr Colon expr
| <assoc = right> expr Equal expr
| identifier = id
| flowControl
| INT
| String
;
flowControl:
Return expr # Return
| Continue # Continue
;
id: ID;
array : OpenCurly el += INT (Comma el += INT)* CloseCurly;
idarray : OpenCurly element += id (Comma element += id)* CloseCurly;
any: t = .;
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="generated">
<UniqueIdentifier>{ef397b7b-1192-4d44-93ed-fadaec7622e8}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\generated\TParser.cpp">
<Filter>generated</Filter>
</ClCompile>
<ClCompile Include="..\..\generated\TParserBaseListener.cpp">
<Filter>generated</Filter>
</ClCompile>
<ClCompile Include="..\..\generated\TParserBaseVisitor.cpp">
<Filter>generated</Filter>
</ClCompile>
<ClCompile Include="..\..\generated\TParserListener.cpp">
<Filter>generated</Filter>
</ClCompile>
<ClCompile Include="..\..\generated\TParserVisitor.cpp">
<Filter>generated</Filter>
</ClCompile>
<ClCompile Include="..\..\generated\TLexer.cpp">
<Filter>generated</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\generated\TLexer.h">
<Filter>generated</Filter>
</ClInclude>
<ClInclude Include="..\..\generated\TParser.h">
<Filter>generated</Filter>
</ClInclude>
<ClInclude Include="..\..\generated\TParserBaseListener.h">
<Filter>generated</Filter>
</ClInclude>
<ClInclude Include="..\..\generated\TParserBaseVisitor.h">
<Filter>generated</Filter>
</ClInclude>
<ClInclude Include="..\..\generated\TParserListener.h">
<Filter>generated</Filter>
</ClInclude>
<ClInclude Include="..\..\generated\TParserVisitor.h">
<Filter>generated</Filter>
</ClInclude>
</ItemGroup>
</Project>
\ No newline at end of file
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
//
// main.cpp
// antlr4-cpp-demo
//
// Created by Mike Lischke on 13.03.16.
//
#include <iostream>
#include "TLexer.h"
#include "TParser.h"
#include "antlr4-runtime.h"
#include <Windows.h>
#pragma execution_character_set("utf-8")
using namespace antlrcpptest;
using namespace antlr4;
int main(int argc, const char* argv[]) {
ANTLRInputStream input(
"🍴 = 🍐 + \"😎\";(((x * π))) * µ + ∰; a + (x * (y ? 0 : 1) + z);");
TLexer lexer(&input);
CommonTokenStream tokens(&lexer);
TParser parser(&tokens);
tree::ParseTree* tree = parser.main();
std::wstring s = antlrcpp::s2ws(tree->toStringTree(&parser)) + L"\n";
OutputDebugString(s.data()); // Only works properly since VS 2015.
// std::wcout << "Parse Tree: " << s << std::endl; Unicode output in the
// console is very limited.
return 0;
}
@echo off
:: Created 2016, Mike Lischke (public domain)
:: This script is used to generate source files from the test grammars in the same folder. The generated files are placed
:: into a subfolder "generated" which the demo project uses to compile a demo binary.
:: Download the ANLTR jar and place it in the same folder as this script (or adjust the LOCATION var accordingly).
set LOCATION=antlr-4.7.1-complete.jar
java -jar %LOCATION% -Dlanguage=Cpp -listener -visitor -o generated/ -package antlrcpptest TLexer.g4 TParser.g4
::java -jar %LOCATION% -Dlanguage=Cpp -listener -visitor -o generated/ -package antlrcpptest -XdbgST TLexer.g4 TParser.g4
::java -jar %LOCATION% -Dlanguage=Java -listener -visitor -o generated/ -package antlrcpptest TLexer.g4 TParser.g4
#!/bin/bash
set -o errexit
# Created 2016, Mike Lischke (public domain)
# This script is used to generate source files from the test grammars in the same folder. The generated files are placed
# into a subfolder "generated" which the demo project uses to compile a demo binary.
# There are 2 ways of running the ANTLR generator here.
# 1) Running from jar. Use the given jar (or replace it by another one you built or downloaded) for generation.
#LOCATION=antlr4-4.5.4-SNAPSHOT.jar
#java -jar $LOCATION -Dlanguage=Cpp -listener -visitor -o generated/ -package antlrcpptest TLexer.g4 TParser.g4
#java -jar $LOCATION -Dlanguage=Cpp -listener -visitor -o generated/ -package antlrcpptest -XdbgST TLexer.g4 TParser.g4
#java -jar $LOCATION -Dlanguage=Java -listener -visitor -o generated/ -package antlrcpptest TLexer.g4 TParser.g4
# 2) Running from class path. This requires that you have both antlr3 and antlr4 compiled. In this scenario no installation
# is needed. You just compile the java class files (using "mvn compile" in both the antlr4 and the antlr3 root folders).
# The script then runs the generation using these class files, by specifying them on the classpath.
# Also the string template jar is needed. Adjust CLASSPATH if you have stored the jar in a different folder as this script assumes.
# Furthermore is assumed that the antlr3 folder is located side-by-side with the antlr4 folder. Adjust CLASSPATH if not.
# This approach is especially useful if you are working on a target stg file, as it doesn't require to regenerate the
# antlr jar over and over again.
CLASSPATH=../../../tool/resources/:ST-4.0.8.jar:../../../tool/target/classes:../../../runtime/Java/target/classes:../../../../antlr3/runtime/Java/target/classes
java -cp $CLASSPATH org.antlr.v4.Tool -Dlanguage=Cpp -listener -visitor -o generated/ -package antlrcpptest TLexer.g4 TParser.g4
#java -cp $CLASSPATH org.antlr.v4.Tool -Dlanguage=Cpp -listener -visitor -o generated/ -package antlrcpptest -XdbgST TLexer.g4 TParser.g4
#java -cp $CLASSPATH org.antlr.v4.Tool -Dlanguage=Java -listener -visitor -o generated/ TLexer.g4 TParser.g4
#!/bin/bash
# Clean left overs from previous builds if there are any
rm -f -R antlr4-runtime build lib 2> /dev/null
rm antlr4-cpp-runtime-macos.zip 2> /dev/null
# Binaries
xcodebuild -project runtime/antlrcpp.xcodeproj -target antlr4 -configuration Release
xcodebuild -project runtime/antlrcpp.xcodeproj -target antlr4_static -configuration Release
rm -f -R lib
mkdir lib
mv runtime/build/Release/libantlr4-runtime.a lib/
mv runtime/build/Release/libantlr4-runtime.dylib lib/
# Headers
rm -f -R antlr4-runtime
pushd runtime/src
find . -name '*.h' | cpio -pdm ../../antlr4-runtime
popd
# Zip up and clean up
zip -r antlr4-cpp-runtime-macos.zip antlr4-runtime lib
rm -f -R antlr4-runtime build lib
# Deploy
#cp antlr4-cpp-runtime-macos.zip ~/antlr/sites/website-antlr4/download
#!/bin/bash
# Zip it
rm -f antlr4-cpp-runtime-source.zip
zip -r antlr4-cpp-runtime-source.zip "README.md" "cmake" "demo" "runtime" "CMakeLists.txt" "deploy-macos.sh" "deploy-source.sh" "deploy-windows.cmd" "VERSION" \
-X -x "*.DS_Store*" "antlrcpp.xcodeproj/xcuserdata/*" "*Build*" "*DerivedData*" "*.jar" "demo/generated/*" "*.vscode*" "runtime/build/*"
# Add the license file from the ANTLR root as well.
pushd ../../
zip runtime/cpp/antlr4-cpp-runtime-source.zip LICENSE.txt
popd
# Deploy
#cp antlr4-cpp-runtime-source.zip ~/antlr/sites/website-antlr4/download
@echo off
rem Clean left overs from previous builds if there are any
if exist bin rmdir /S /Q runtime\bin
if exist obj rmdir /S /Q runtime\obj
if exist lib rmdir /S /Q lib
if exist antlr4-runtime rmdir /S /Q antlr4-runtime
if exist antlr4-cpp-runtime-vs2013.zip erase antlr4-cpp-runtime-vs2013.zip
if exist antlr4-cpp-runtime-vs2015.zip erase antlr4-cpp-runtime-vs2015.zip
rem Headers
xcopy runtime\src\*.h antlr4-runtime\ /s
rem Binaries
rem VS 2013 disabled by default. Change the X to a C to enable it.
if exist "X:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\VsDevCmd.bat" (
call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\VsDevCmd.bat"
pushd runtime
msbuild antlr4cpp-vs2013.vcxproj /p:configuration="Release DLL" /p:platform=Win32
msbuild antlr4cpp-vs2013.vcxproj /p:configuration="Release DLL" /p:platform=x64
popd
7z a antlr4-cpp-runtime-vs2013.zip antlr4-runtime
xcopy runtime\bin\*.dll lib\ /s
xcopy runtime\bin\*.lib lib\ /s
7z a antlr4-cpp-runtime-vs2013.zip lib
rmdir /S /Q lib
rmdir /S /Q runtime\bin
rmdir /S /Q runtime\obj
rem if exist antlr4-cpp-runtime-vs2013.zip copy antlr4-cpp-runtime-vs2013.zip ~/antlr/sites/website-antlr4/download
)
if exist "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\VsDevCmd.bat" (
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\VsDevCmd.bat"
pushd runtime
msbuild antlr4cpp-vs2015.vcxproj /p:configuration="Release DLL" /p:platform=Win32
msbuild antlr4cpp-vs2015.vcxproj /p:configuration="Release DLL" /p:platform=x64
popd
7z a antlr4-cpp-runtime-vs2015.zip antlr4-runtime
xcopy runtime\bin\*.dll lib\ /s
xcopy runtime\bin\*.lib lib\ /s
7z a antlr4-cpp-runtime-vs2015.zip lib
rmdir /S /Q lib
rmdir /S /Q runtime\bin
rmdir /S /Q runtime\obj
rem if exist antlr4-cpp-runtime-vs2015.zip copy antlr4-cpp-runtime-vs2015.zip ~/antlr/sites/website-antlr4/download
)
rmdir /S /Q antlr4-runtime
:end
include_directories(
${PROJECT_SOURCE_DIR}/runtime/src
${PROJECT_SOURCE_DIR}/runtime/src/atn
${PROJECT_SOURCE_DIR}/runtime/src/dfa
${PROJECT_SOURCE_DIR}/runtime/src/misc
${PROJECT_SOURCE_DIR}/runtime/src/support
${PROJECT_SOURCE_DIR}/runtime/src/tree
${PROJECT_SOURCE_DIR}/runtime/src/tree/pattern
${PROJECT_SOURCE_DIR}/runtime/src/tree/xpath
)
file(GLOB libantlrcpp_SRC
"${PROJECT_SOURCE_DIR}/runtime/src/*.cpp"
"${PROJECT_SOURCE_DIR}/runtime/src/atn/*.cpp"
"${PROJECT_SOURCE_DIR}/runtime/src/dfa/*.cpp"
"${PROJECT_SOURCE_DIR}/runtime/src/misc/*.cpp"
"${PROJECT_SOURCE_DIR}/runtime/src/support/*.cpp"
"${PROJECT_SOURCE_DIR}/runtime/src/tree/*.cpp"
"${PROJECT_SOURCE_DIR}/runtime/src/tree/pattern/*.cpp"
"${PROJECT_SOURCE_DIR}/runtime/src/tree/xpath/*.cpp"
)
add_library(antlr4_shared SHARED ${libantlrcpp_SRC})
add_library(antlr4_static STATIC ${libantlrcpp_SRC})
set(LIB_OUTPUT_DIR "${CMAKE_HOME_DIRECTORY}/dist") # put generated libraries here.
message(STATUS "Output libraries to ${LIB_OUTPUT_DIR}")
# make sure 'make' works fine even if ${LIB_OUTPUT_DIR} is deleted.
add_custom_target(make_lib_output_dir ALL
COMMAND ${CMAKE_COMMAND} -E make_directory ${LIB_OUTPUT_DIR}
)
add_dependencies(antlr4_shared make_lib_output_dir)
add_dependencies(antlr4_static make_lib_output_dir)
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
target_link_libraries(antlr4_shared ${UUID_LIBRARIES})
target_link_libraries(antlr4_static ${UUID_LIBRARIES})
elseif(APPLE)
target_link_libraries(antlr4_shared ${COREFOUNDATION_LIBRARY})
target_link_libraries(antlr4_static ${COREFOUNDATION_LIBRARY})
endif()
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
set(disabled_compile_warnings "/wd4251")
else()
set(disabled_compile_warnings "-Wno-overloaded-virtual")
endif ()
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
set(disabled_compile_warnings "${disabled_compile_warnings} -Wno-dollar-in-identifier-extension -Wno-four-char-constants")
elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Intel")
set(disabled_compile_warnings "${disabled_compile_warnings} -Wno-multichar")
endif()
set(extra_share_compile_flags "")
set(extra_static_compile_flags "")
if (WIN32)
set(extra_share_compile_flags "-DANTLR4CPP_EXPORTS")
set(extra_static_compile_flags "-DANTLR4CPP_STATIC")
endif(WIN32)
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
target_compile_options(antlr4_shared PRIVATE "/MD$<$<CONFIG:Debug>:d>")
target_compile_options(antlr4_static PRIVATE "/MT$<$<CONFIG:Debug>:d>")
endif()
set(static_lib_suffix "")
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
set(static_lib_suffix "-static")
endif()
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
set(extra_share_compile_flags "-DANTLR4CPP_EXPORTS -MP /wd4251")
set(extra_static_compile_flags "-DANTLR4CPP_STATIC -MP")
endif()
set_target_properties(antlr4_shared
PROPERTIES VERSION ${ANTLR_VERSION}
SOVERSION ${ANTLR_VERSION}
OUTPUT_NAME antlr4-runtime
LIBRARY_OUTPUT_DIRECTORY ${LIB_OUTPUT_DIR}
# TODO: test in windows. DLL is treated as runtime.
# see https://cmake.org/cmake/help/v3.0/prop_tgt/LIBRARY_OUTPUT_DIRECTORY.html
RUNTIME_OUTPUT_DIRECTORY ${LIB_OUTPUT_DIR}
ARCHIVE_OUTPUT_DIRECTORY ${LIB_OUTPUT_DIR}
COMPILE_FLAGS "${disabled_compile_warnings} ${extra_share_compile_flags}")
set_target_properties(antlr4_static
PROPERTIES VERSION ${ANTLR_VERSION}
SOVERSION ${ANTLR_VERSION}
OUTPUT_NAME "antlr4-runtime${static_lib_suffix}"
ARCHIVE_OUTPUT_DIRECTORY ${LIB_OUTPUT_DIR}
COMPILE_FLAGS "${disabled_compile_warnings} ${extra_static_compile_flags}")
install(TARGETS antlr4_shared
DESTINATION lib)
install(TARGETS antlr4_static
ARCHIVE DESTINATION lib)
install(DIRECTORY "${PROJECT_SOURCE_DIR}/runtime/src/"
DESTINATION "include/antlr4-runtime"
COMPONENT dev
FILES_MATCHING PATTERN "*.h"
)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>
//
// antlrcpp-ios.h
// antlrcpp-ios
//
// Created by Mike Lischke on 05.05.16.
// Copyright © 2016 Mike Lischke. All rights reserved.
//
#import <UIKit/UIKit.h>
//! Project version number for antlrcpp-ios.
FOUNDATION_EXPORT double antlrcpp_iosVersionNumber;
//! Project version string for antlrcpp-ios.
FOUNDATION_EXPORT const unsigned char antlrcpp_iosVersionString[];
#include "antlr4-runtime.h"
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#include "ANTLRErrorListener.h"
antlr4::ANTLRErrorListener::~ANTLRErrorListener() {}
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#pragma once
#include "RecognitionException.h"
namespace antlrcpp {
class BitSet;
}
namespace antlr4 {
/// How to emit recognition errors (an interface in Java).
class ANTLR4CPP_PUBLIC ANTLRErrorListener {
public:
virtual ~ANTLRErrorListener();
/// <summary>
/// Upon syntax error, notify any interested parties. This is not how to
/// recover from errors or compute error messages. <seealso
/// cref="ANTLRErrorStrategy"/> specifies how to recover from syntax errors
/// and how to compute error messages. This listener's job is simply to emit a
/// computed message, though it has enough information to create its own
/// message in many cases. <p/> The <seealso cref="RecognitionException"/> is
/// non-null for all syntax errors except when we discover mismatched token
/// errors that we can recover from in-line, without returning from the
/// surrounding rule (via the single token insertion and deletion mechanism).
/// </summary>
/// <param name="recognizer">
/// What parser got the error. From this
/// object, you can access the context as well
/// as the input stream. </param>
/// <param name="offendingSymbol">
/// The offending token in the input token
/// stream, unless recognizer is a lexer (then it's null). If
/// no viable alternative error, {@code e} has token at which we
/// started production for the decision. </param>
/// <param name="line">
/// The line number in the input where the error occurred.
/// </param> <param name="charPositionInLine"> The character
/// position within that line where the error occurred. </param> <param
/// name="msg"> The message to emit. </param> <param name="e">
/// The exception generated by the parser that led to
/// the reporting of an error. It is null in the case where
/// the parser was able to recover in line without exiting the
/// surrounding rule. </param>
virtual void syntaxError(Recognizer* recognizer, Token* offendingSymbol,
size_t line, size_t charPositionInLine,
const std::string& msg, std::exception_ptr e) = 0;
/**
* This method is called by the parser when a full-context prediction
* results in an ambiguity.
*
* <p>Each full-context prediction which does not result in a syntax error
* will call either {@link #reportContextSensitivity} or
* {@link #reportAmbiguity}.</p>
*
* <p>When {@code ambigAlts} is not null, it contains the set of potentially
* viable alternatives identified by the prediction algorithm. When
* {@code ambigAlts} is null, use {@link ATNConfigSet#getAlts} to obtain the
* represented alternatives from the {@code configs} argument.</p>
*
* <p>When {@code exact} is {@code true}, <em>all</em> of the potentially
* viable alternatives are truly viable, i.e. this is reporting an exact
* ambiguity. When {@code exact} is {@code false}, <em>at least two</em> of
* the potentially viable alternatives are viable for the current input, but
* the prediction algorithm terminated as soon as it determined that at
* least the <em>minimum</em> potentially viable alternative is truly
* viable.</p>
*
* <p>When the {@link PredictionMode#LL_EXACT_AMBIG_DETECTION} prediction
* mode is used, the parser is required to identify exact ambiguities so
* {@code exact} will always be {@code true}.</p>
*
* <p>This method is not used by lexers.</p>
*
* @param recognizer the parser instance
* @param dfa the DFA for the current decision
* @param startIndex the input index where the decision started
* @param stopIndex the input input where the ambiguity was identified
* @param exact {@code true} if the ambiguity is exactly known, otherwise
* {@code false}. This is always {@code true} when
* {@link PredictionMode#LL_EXACT_AMBIG_DETECTION} is used.
* @param ambigAlts the potentially ambiguous alternatives, or {@code null}
* to indicate that the potentially ambiguous alternatives are the complete
* set of represented alternatives in {@code configs}
* @param configs the ATN configuration set where the ambiguity was
* identified
*/
virtual void reportAmbiguity(Parser* recognizer, const dfa::DFA& dfa,
size_t startIndex, size_t stopIndex, bool exact,
const antlrcpp::BitSet& ambigAlts,
atn::ATNConfigSet* configs) = 0;
/**
* This method is called when an SLL conflict occurs and the parser is about
* to use the full context information to make an LL decision.
*
* <p>If one or more configurations in {@code configs} contains a semantic
* predicate, the predicates are evaluated before this method is called. The
* subset of alternatives which are still viable after predicates are
* evaluated is reported in {@code conflictingAlts}.</p>
*
* <p>This method is not used by lexers.</p>
*
* @param recognizer the parser instance
* @param dfa the DFA for the current decision
* @param startIndex the input index where the decision started
* @param stopIndex the input index where the SLL conflict occurred
* @param conflictingAlts The specific conflicting alternatives. If this is
* {@code null}, the conflicting alternatives are all alternatives
* represented in {@code configs}. At the moment, conflictingAlts is non-null
* (for the reference implementation, but Sam's optimized version can see this
* as null).
* @param configs the ATN configuration set where the SLL conflict was
* detected
*/
virtual void reportAttemptingFullContext(
Parser* recognizer, const dfa::DFA& dfa, size_t startIndex,
size_t stopIndex, const antlrcpp::BitSet& conflictingAlts,
atn::ATNConfigSet* configs) = 0;
/**
* This method is called by the parser when a full-context prediction has a
* unique result.
*
* <p>Each full-context prediction which does not result in a syntax error
* will call either {@link #reportContextSensitivity} or
* {@link #reportAmbiguity}.</p>
*
* <p>For prediction implementations that only evaluate full-context
* predictions when an SLL conflict is found (including the default
* {@link ParserATNSimulator} implementation), this method reports cases
* where SLL conflicts were resolved to unique full-context predictions,
* i.e. the decision was context-sensitive. This report does not necessarily
* indicate a problem, and it may appear even in completely unambiguous
* grammars.</p>
*
* <p>{@code configs} may have more than one represented alternative if the
* full-context prediction algorithm does not evaluate predicates before
* beginning the full-context prediction. In all cases, the final prediction
* is passed as the {@code prediction} argument.</p>
*
* <p>Note that the definition of "context sensitivity" in this method
* differs from the concept in {@link DecisionInfo#contextSensitivities}.
* This method reports all instances where an SLL conflict occurred but LL
* parsing produced a unique result, whether or not that unique result
* matches the minimum alternative in the SLL conflicting set.</p>
*
* <p>This method is not used by lexers.</p>
*
* @param recognizer the parser instance
* @param dfa the DFA for the current decision
* @param startIndex the input index where the decision started
* @param stopIndex the input index where the context sensitivity was
* finally determined
* @param prediction the unambiguous result of the full-context prediction
* @param configs the ATN configuration set where the unambiguous prediction
* was determined
*/
virtual void reportContextSensitivity(Parser* recognizer, const dfa::DFA& dfa,
size_t startIndex, size_t stopIndex,
size_t prediction,
atn::ATNConfigSet* configs) = 0;
};
} // namespace antlr4
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#include "ANTLRErrorStrategy.h"
antlr4::ANTLRErrorStrategy::~ANTLRErrorStrategy() {}
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#pragma once
#include "Token.h"
namespace antlr4 {
/// <summary>
/// The interface for defining strategies to deal with syntax errors encountered
/// during a parse by ANTLR-generated parsers. We distinguish between three
/// different kinds of errors:
///
/// <ul>
/// <li>The parser could not figure out which path to take in the ATN (none of
/// the available alternatives could possibly match)</li>
/// <li>The current input does not match what we were looking for</li>
/// <li>A predicate evaluated to false</li>
/// </ul>
///
/// Implementations of this interface report syntax errors by calling
/// <seealso cref="Parser#notifyErrorListeners"/>.
/// <p/>
/// TO_DO: what to do about lexers
/// </summary>
class ANTLR4CPP_PUBLIC ANTLRErrorStrategy {
public:
/// <summary>
/// Reset the error handler state for the specified {@code recognizer}.
/// </summary> <param name="recognizer"> the parser instance </param>
virtual ~ANTLRErrorStrategy();
virtual void reset(Parser* recognizer) = 0;
/**
* This method is called when an unexpected symbol is encountered during an
* inline match operation, such as {@link Parser#match}. If the error
* strategy successfully recovers from the match failure, this method
* returns the {@link Token} instance which should be treated as the
* successful result of the match.
*
* <p>This method handles the consumption of any tokens - the caller should
* <b>not</b> call {@link Parser#consume} after a successful recovery.</p>
*
* <p>Note that the calling code will not report an error if this method
* returns successfully. The error strategy implementation is responsible
* for calling {@link Parser#notifyErrorListeners} as appropriate.</p>
*
* @param recognizer the parser instance
* @throws RecognitionException if the error strategy was not able to
* recover from the unexpected input symbol
*/
virtual Token* recoverInline(Parser* recognizer) = 0;
/// <summary>
/// This method is called to recover from exception {@code e}. This method is
/// called after <seealso cref="#reportError"/> by the default exception
/// handler generated for a rule method.
/// </summary>
/// <seealso cref= #reportError
/// </seealso>
/// <param name="recognizer"> the parser instance </param>
/// <param name="e"> the recognition exception to recover from </param>
/// <exception cref="RecognitionException"> if the error strategy could not
/// recover from the recognition exception </exception>
virtual void recover(Parser* recognizer, std::exception_ptr e) = 0;
/// <summary>
/// This method provides the error handler with an opportunity to handle
/// syntactic or semantic errors in the input stream before they result in a
/// <seealso cref="RecognitionException"/>.
/// <p/>
/// The generated code currently contains calls to <seealso cref="#sync"/>
/// after entering the decision state of a closure block ({@code (...)*} or
/// {@code (...)+}).
/// <p/>
/// For an implementation based on Jim Idle's "magic sync" mechanism, see
/// <seealso cref="DefaultErrorStrategy#sync"/>.
/// </summary>
/// <seealso cref= DefaultErrorStrategy#sync
/// </seealso>
/// <param name="recognizer"> the parser instance </param>
/// <exception cref="RecognitionException"> if an error is detected by the
/// error strategy but cannot be automatically recovered at the current state
/// in the parsing process </exception>
virtual void sync(Parser* recognizer) = 0;
/// <summary>
/// Tests whether or not {@code recognizer} is in the process of recovering
/// from an error. In error recovery mode, <seealso cref="Parser#consume"/>
/// adds symbols to the parse tree by calling
/// {@link Parser#createErrorNode(ParserRuleContext, Token)} then
/// {@link ParserRuleContext#addErrorNode(ErrorNode)} instead of
/// {@link Parser#createTerminalNode(ParserRuleContext, Token)}.
/// </summary>
/// <param name="recognizer"> the parser instance </param>
/// <returns> {@code true} if the parser is currently recovering from a parse
/// error, otherwise {@code false} </returns>
virtual bool inErrorRecoveryMode(Parser* recognizer) = 0;
/// <summary>
/// This method is called by when the parser successfully matches an input
/// symbol.
/// </summary>
/// <param name="recognizer"> the parser instance </param>
virtual void reportMatch(Parser* recognizer) = 0;
/// <summary>
/// Report any kind of <seealso cref="RecognitionException"/>. This method is
/// called by the default exception handler generated for a rule method.
/// </summary>
/// <param name="recognizer"> the parser instance </param>
/// <param name="e"> the recognition exception to report </param>
virtual void reportError(Parser* recognizer,
const RecognitionException& e) = 0;
};
} // namespace antlr4
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#include "support/StringUtils.h"
#include "ANTLRFileStream.h"
using namespace antlr4;
ANTLRFileStream::ANTLRFileStream(const std::string& fileName) {
_fileName = fileName;
loadFromFile(fileName);
}
void ANTLRFileStream::loadFromFile(const std::string& fileName) {
_fileName = fileName;
if (_fileName.empty()) {
return;
}
#ifdef _MSC_VER
std::ifstream stream(antlrcpp::s2ws(fileName), std::ios::binary);
#else
std::ifstream stream(fileName, std::ios::binary);
#endif
ANTLRInputStream::load(stream);
}
std::string ANTLRFileStream::getSourceName() const { return _fileName; }
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#pragma once
#include "ANTLRInputStream.h"
namespace antlr4 {
/// This is an ANTLRInputStream that is loaded from a file all at once
/// when you construct the object (or call load()).
// TODO: this class needs testing.
class ANTLR4CPP_PUBLIC ANTLRFileStream : public ANTLRInputStream {
protected:
std::string _fileName; // UTF-8 encoded file name.
public:
// Assumes a file name encoded in UTF-8 and file content in the same encoding
// (with or w/o BOM).
ANTLRFileStream(const std::string& fileName);
virtual void loadFromFile(const std::string& fileName);
virtual std::string getSourceName() const override;
};
} // namespace antlr4
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#include "Exceptions.h"
#include "IntStream.h"
#include "misc/Interval.h"
#include "support/CPPUtils.h"
#include "support/StringUtils.h"
#include "ANTLRInputStream.h"
using namespace antlr4;
using namespace antlrcpp;
using misc::Interval;
ANTLRInputStream::ANTLRInputStream(const std::string& input) {
InitializeInstanceFields();
load(input);
}
ANTLRInputStream::ANTLRInputStream(const char data_[],
size_t numberOfActualCharsInArray)
: ANTLRInputStream(std::string(data_, numberOfActualCharsInArray)) {}
ANTLRInputStream::ANTLRInputStream(std::istream& stream) {
InitializeInstanceFields();
load(stream);
}
void ANTLRInputStream::load(const std::string& input) {
// Remove the UTF-8 BOM if present.
const char bom[4] = "\xef\xbb\xbf";
if (input.compare(0, 3, bom, 3) == 0)
_data =
antlrcpp::utf8_to_utf32(input.data() + 3, input.data() + input.size());
else
_data = antlrcpp::utf8_to_utf32(input.data(), input.data() + input.size());
p = 0;
}
void ANTLRInputStream::load(std::istream& stream) {
if (!stream.good() || stream.eof()) // No fail, bad or EOF.
return;
_data.clear();
std::string s((std::istreambuf_iterator<char>(stream)),
std::istreambuf_iterator<char>());
load(s);
}
void ANTLRInputStream::reset() { p = 0; }
void ANTLRInputStream::consume() {
if (p >= _data.size()) {
assert(LA(1) == IntStream::EOF);
throw IllegalStateException("cannot consume EOF");
}
if (p < _data.size()) {
p++;
}
}
size_t ANTLRInputStream::LA(ssize_t i) {
if (i == 0) {
return 0; // undefined
}
ssize_t position = static_cast<ssize_t>(p);
if (i < 0) {
i++; // e.g., translate LA(-1) to use offset i=0; then _data[p+0-1]
if ((position + i - 1) < 0) {
return IntStream::EOF; // invalid; no char before first char
}
}
if ((position + i - 1) >= static_cast<ssize_t>(_data.size())) {
return IntStream::EOF;
}
return _data[static_cast<size_t>((position + i - 1))];
}
size_t ANTLRInputStream::LT(ssize_t i) { return LA(i); }
size_t ANTLRInputStream::index() { return p; }
size_t ANTLRInputStream::size() { return _data.size(); }
// Mark/release do nothing. We have entire buffer.
ssize_t ANTLRInputStream::mark() { return -1; }
void ANTLRInputStream::release(ssize_t /* marker */) {}
void ANTLRInputStream::seek(size_t index) {
if (index <= p) {
p = index; // just jump; don't update stream state (line, ...)
return;
}
// seek forward, consume until p hits index or n (whichever comes first)
index = std::min(index, _data.size());
while (p < index) {
consume();
}
}
std::string ANTLRInputStream::getText(const Interval& interval) {
if (interval.a < 0 || interval.b < 0) {
return "";
}
size_t start = static_cast<size_t>(interval.a);
size_t stop = static_cast<size_t>(interval.b);
if (stop >= _data.size()) {
stop = _data.size() - 1;
}
size_t count = stop - start + 1;
if (start >= _data.size()) {
return "";
}
return antlrcpp::utf32_to_utf8(_data.substr(start, count));
}
std::string ANTLRInputStream::getSourceName() const {
if (name.empty()) {
return IntStream::UNKNOWN_SOURCE_NAME;
}
return name;
}
std::string ANTLRInputStream::toString() const {
return antlrcpp::utf32_to_utf8(_data);
}
void ANTLRInputStream::InitializeInstanceFields() { p = 0; }
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#pragma once
#include "CharStream.h"
namespace antlr4 {
// Vacuum all input from a stream and then treat it
// like a string. Can also pass in a string or char[] to use.
// Input is expected to be encoded in UTF-8 and converted to UTF-32 internally.
class ANTLR4CPP_PUBLIC ANTLRInputStream : public CharStream {
protected:
/// The data being scanned.
// UTF-32
UTF32String _data;
/// 0..n-1 index into string of next char </summary>
size_t p;
public:
/// What is name or source of this char stream?
std::string name;
ANTLRInputStream(const std::string& input = "");
ANTLRInputStream(const char data_[], size_t numberOfActualCharsInArray);
ANTLRInputStream(std::istream& stream);
virtual void load(const std::string& input);
virtual void load(std::istream& stream);
/// Reset the stream so that it's in the same state it was
/// when the object was created *except* the data array is not
/// touched.
virtual void reset();
virtual void consume() override;
virtual size_t LA(ssize_t i) override;
virtual size_t LT(ssize_t i);
/// <summary>
/// Return the current input symbol index 0..n where n indicates the
/// last symbol has been read. The index is the index of char to
/// be returned from LA(1).
/// </summary>
virtual size_t index() override;
virtual size_t size() override;
/// <summary>
/// mark/release do nothing; we have entire buffer </summary>
virtual ssize_t mark() override;
virtual void release(ssize_t marker) override;
/// <summary>
/// consume() ahead until p==index; can't just set p=index as we must
/// update line and charPositionInLine. If we seek backwards, just set p
/// </summary>
virtual void seek(size_t index) override;
virtual std::string getText(const misc::Interval& interval) override;
virtual std::string getSourceName() const override;
virtual std::string toString() const override;
private:
void InitializeInstanceFields();
};
} // namespace antlr4
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#include "Exceptions.h"
#include "InputMismatchException.h"
#include "Parser.h"
#include "ParserRuleContext.h"
#include "BailErrorStrategy.h"
using namespace antlr4;
void BailErrorStrategy::recover(Parser* recognizer, std::exception_ptr e) {
ParserRuleContext* context = recognizer->getContext();
do {
context->exception = e;
if (context->parent == nullptr) break;
context = static_cast<ParserRuleContext*>(context->parent);
} while (true);
try {
std::rethrow_exception(
e); // Throw the exception to be able to catch and rethrow nested.
#if defined(_MSC_FULL_VER) && _MSC_FULL_VER < 190023026
} catch (RecognitionException& inner) {
throw ParseCancellationException(inner.what());
#else
} catch (RecognitionException& /*inner*/) {
std::throw_with_nested(ParseCancellationException());
#endif
}
}
Token* BailErrorStrategy::recoverInline(Parser* recognizer) {
InputMismatchException e(recognizer);
std::exception_ptr exception = std::make_exception_ptr(e);
ParserRuleContext* context = recognizer->getContext();
do {
context->exception = exception;
if (context->parent == nullptr) break;
context = static_cast<ParserRuleContext*>(context->parent);
} while (true);
try {
throw e;
#if defined(_MSC_FULL_VER) && _MSC_FULL_VER < 190023026
} catch (InputMismatchException& inner) {
throw ParseCancellationException(inner.what());
#else
} catch (InputMismatchException& /*inner*/) {
std::throw_with_nested(ParseCancellationException());
#endif
}
}
void BailErrorStrategy::sync(Parser* /*recognizer*/) {}
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#pragma once
#include "DefaultErrorStrategy.h"
namespace antlr4 {
/**
* This implementation of {@link ANTLRErrorStrategy} responds to syntax errors
* by immediately canceling the parse operation with a
* {@link ParseCancellationException}. The implementation ensures that the
* {@link ParserRuleContext#exception} field is set for all parse tree nodes
* that were not completed prior to encountering the error.
*
* <p>
* This error strategy is useful in the following scenarios.</p>
*
* <ul>
* <li><strong>Two-stage parsing:</strong> This error strategy allows the first
* stage of two-stage parsing to immediately terminate if an error is
* encountered, and immediately fall back to the second stage. In addition to
* avoiding wasted work by attempting to recover from errors here, the empty
* implementation of {@link BailErrorStrategy#sync} improves the performance of
* the first stage.</li>
* <li><strong>Silent validation:</strong> When syntax errors are not being
* reported or logged, and the parse result is simply ignored if errors occur,
* the {@link BailErrorStrategy} avoids wasting work on recovering from errors
* when the result will be ignored either way.</li>
* </ul>
*
* <p>
* {@code myparser.setErrorHandler(new BailErrorStrategy());}</p>
*
* @see Parser#setErrorHandler(ANTLRErrorStrategy)
*/
class ANTLR4CPP_PUBLIC BailErrorStrategy : public DefaultErrorStrategy {
/// <summary>
/// Instead of recovering from exception {@code e}, re-throw it wrapped
/// in a <seealso cref="ParseCancellationException"/> so it is not caught by
/// the rule function catches. Use <seealso cref="Exception#getCause()"/> to
/// get the original <seealso cref="RecognitionException"/>.
/// </summary>
public:
virtual void recover(Parser* recognizer, std::exception_ptr e) override;
/// Make sure we don't attempt to recover inline; if the parser
/// successfully recovers, it won't throw an exception.
virtual Token* recoverInline(Parser* recognizer) override;
/// <summary>
/// Make sure we don't attempt to recover from problems in subrules.
/// </summary>
virtual void sync(Parser* recognizer) override;
};
} // namespace antlr4
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#include "BaseErrorListener.h"
#include "RecognitionException.h"
using namespace antlr4;
void BaseErrorListener::syntaxError(Recognizer* /*recognizer*/,
Token* /*offendingSymbol*/, size_t /*line*/,
size_t /*charPositionInLine*/,
const std::string& /*msg*/,
std::exception_ptr /*e*/) {}
void BaseErrorListener::reportAmbiguity(Parser* /*recognizer*/,
const dfa::DFA& /*dfa*/,
size_t /*startIndex*/,
size_t /*stopIndex*/, bool /*exact*/,
const antlrcpp::BitSet& /*ambigAlts*/,
atn::ATNConfigSet* /*configs*/) {}
void BaseErrorListener::reportAttemptingFullContext(
Parser* /*recognizer*/, const dfa::DFA& /*dfa*/, size_t /*startIndex*/,
size_t /*stopIndex*/, const antlrcpp::BitSet& /*conflictingAlts*/,
atn::ATNConfigSet* /*configs*/) {}
void BaseErrorListener::reportContextSensitivity(
Parser* /*recognizer*/, const dfa::DFA& /*dfa*/, size_t /*startIndex*/,
size_t /*stopIndex*/, size_t /*prediction*/,
atn::ATNConfigSet* /*configs*/) {}
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#pragma once
#include "ANTLRErrorListener.h"
namespace antlrcpp {
class BitSet;
}
namespace antlr4 {
/**
* Provides an empty default implementation of {@link ANTLRErrorListener}. The
* default implementation of each method does nothing, but can be overridden as
* necessary.
*/
class ANTLR4CPP_PUBLIC BaseErrorListener : public ANTLRErrorListener {
virtual void syntaxError(Recognizer* recognizer, Token* offendingSymbol,
size_t line, size_t charPositionInLine,
const std::string& msg,
std::exception_ptr e) override;
virtual void reportAmbiguity(Parser* recognizer, const dfa::DFA& dfa,
size_t startIndex, size_t stopIndex, bool exact,
const antlrcpp::BitSet& ambigAlts,
atn::ATNConfigSet* configs) override;
virtual void reportAttemptingFullContext(
Parser* recognizer, const dfa::DFA& dfa, size_t startIndex,
size_t stopIndex, const antlrcpp::BitSet& conflictingAlts,
atn::ATNConfigSet* configs) override;
virtual void reportContextSensitivity(Parser* recognizer, const dfa::DFA& dfa,
size_t startIndex, size_t stopIndex,
size_t prediction,
atn::ATNConfigSet* configs) override;
};
} // namespace antlr4
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#pragma once
#include "TokenStream.h"
namespace antlr4 {
/**
* This implementation of {@link TokenStream} loads tokens from a
* {@link TokenSource} on-demand, and places the tokens in a buffer to provide
* access to any previous token by index.
*
* <p>
* This token stream ignores the value of {@link Token#getChannel}. If your
* parser requires the token stream filter tokens to only those on a particular
* channel, such as {@link Token#DEFAULT_CHANNEL} or
* {@link Token#HIDDEN_CHANNEL}, use a filtering token stream such a
* {@link CommonTokenStream}.</p>
*/
class ANTLR4CPP_PUBLIC BufferedTokenStream : public TokenStream {
public:
BufferedTokenStream(TokenSource* tokenSource);
BufferedTokenStream(const BufferedTokenStream& other) = delete;
BufferedTokenStream& operator=(const BufferedTokenStream& other) = delete;
virtual TokenSource* getTokenSource() const override;
virtual size_t index() override;
virtual ssize_t mark() override;
virtual void release(ssize_t marker) override;
virtual void reset();
virtual void seek(size_t index) override;
virtual size_t size() override;
virtual void consume() override;
virtual Token* get(size_t i) const override;
/// Get all tokens from start..stop inclusively.
virtual std::vector<Token*> get(size_t start, size_t stop);
virtual size_t LA(ssize_t i) override;
virtual Token* LT(ssize_t k) override;
/// Reset this token stream by setting its token source.
virtual void setTokenSource(TokenSource* tokenSource);
virtual std::vector<Token*> getTokens();
virtual std::vector<Token*> getTokens(size_t start, size_t stop);
/// <summary>
/// Given a start and stop index, return a List of all tokens in
/// the token type BitSet. Return null if no tokens were found. This
/// method looks at both on and off channel tokens.
/// </summary>
virtual std::vector<Token*> getTokens(size_t start, size_t stop,
const std::vector<size_t>& types);
virtual std::vector<Token*> getTokens(size_t start, size_t stop,
size_t ttype);
/// Collect all tokens on specified channel to the right of
/// the current token up until we see a token on DEFAULT_TOKEN_CHANNEL or
/// EOF. If channel is -1, find any non default channel token.
virtual std::vector<Token*> getHiddenTokensToRight(size_t tokenIndex,
ssize_t channel);
/// <summary>
/// Collect all hidden tokens (any off-default channel) to the right of
/// the current token up until we see a token on DEFAULT_TOKEN_CHANNEL
/// or EOF.
/// </summary>
virtual std::vector<Token*> getHiddenTokensToRight(size_t tokenIndex);
/// <summary>
/// Collect all tokens on specified channel to the left of
/// the current token up until we see a token on DEFAULT_TOKEN_CHANNEL.
/// If channel is -1, find any non default channel token.
/// </summary>
virtual std::vector<Token*> getHiddenTokensToLeft(size_t tokenIndex,
ssize_t channel);
/// <summary>
/// Collect all hidden tokens (any off-default channel) to the left of
/// the current token up until we see a token on DEFAULT_TOKEN_CHANNEL.
/// </summary>
virtual std::vector<Token*> getHiddenTokensToLeft(size_t tokenIndex);
virtual std::string getSourceName() const override;
virtual std::string getText() override;
virtual std::string getText(const misc::Interval& interval) override;
virtual std::string getText(RuleContext* ctx) override;
virtual std::string getText(Token* start, Token* stop) override;
/// Get all tokens from lexer until EOF.
virtual void fill();
protected:
/**
* The {@link TokenSource} from which tokens for this stream are fetched.
*/
TokenSource* _tokenSource;
/**
* A collection of all tokens fetched from the token source. The list is
* considered a complete view of the input once {@link #fetchedEOF} is set
* to {@code true}.
*/
std::vector<std::unique_ptr<Token>> _tokens;
/**
* The index into {@link #tokens} of the current token (next token to
* {@link #consume}). {@link #tokens}{@code [}{@link #p}{@code ]} should be
* {@link #LT LT(1)}.
*
* <p>This field is set to -1 when the stream is first constructed or when
* {@link #setTokenSource} is called, indicating that the first token has
* not yet been fetched from the token source. For additional information,
* see the documentation of {@link IntStream} for a description of
* Initializing Methods.</p>
*/
// ml: since -1 requires to make this member signed for just this single
// aspect we use a member _needSetup instead.
// Use bool isInitialized() to find out if this stream has started
// reading.
size_t _p;
/**
* Indicates whether the {@link Token#EOF} token has been fetched from
* {@link #tokenSource} and added to {@link #tokens}. This field improves
* performance for the following cases:
*
* <ul>
* <li>{@link #consume}: The lookahead check in {@link #consume} to prevent
* consuming the EOF symbol is optimized by checking the values of
* {@link #fetchedEOF} and {@link #p} instead of calling {@link #LA}.</li>
* <li>{@link #fetch}: The check to prevent adding multiple EOF symbols into
* {@link #tokens} is trivial with this field.</li>
* <ul>
*/
bool _fetchedEOF;
/// <summary>
/// Make sure index {@code i} in tokens has a token.
/// </summary>
/// <returns> {@code true} if a token is located at index {@code i}, otherwise
/// {@code false}. </returns>
/// <seealso cref= #get(int i) </seealso>
virtual bool sync(size_t i);
/// <summary>
/// Add {@code n} elements to buffer.
/// </summary>
/// <returns> The actual number of elements added to the buffer. </returns>
virtual size_t fetch(size_t n);
virtual Token* LB(size_t k);
/// Allowed derived classes to modify the behavior of operations which change
/// the current stream position by adjusting the target token index of a seek
/// operation. The default implementation simply returns {@code i}. If an
/// exception is thrown in this method, the current stream index should not be
/// changed.
/// <p/>
/// For example, <seealso cref="CommonTokenStream"/> overrides this method to
/// ensure that the seek target is always an on-channel token.
///
/// <param name="i"> The target token index. </param>
/// <returns> The adjusted target token index. </returns>
virtual ssize_t adjustSeekIndex(size_t i);
void lazyInit();
virtual void setup();
/**
* Given a starting index, return the index of the next token on channel.
* Return {@code i} if {@code tokens[i]} is on channel. Return the index of
* the EOF token if there are no tokens on channel between {@code i} and
* EOF.
*/
virtual ssize_t nextTokenOnChannel(size_t i, size_t channel);
/**
* Given a starting index, return the index of the previous token on
* channel. Return {@code i} if {@code tokens[i]} is on channel. Return -1
* if there are no tokens on channel between {@code i} and 0.
*
* <p>
* If {@code i} specifies an index at or after the EOF token, the EOF token
* index is returned. This is due to the fact that the EOF token is treated
* as though it were on every channel.</p>
*/
virtual ssize_t previousTokenOnChannel(size_t i, size_t channel);
virtual std::vector<Token*> filterForChannel(size_t from, size_t to,
ssize_t channel);
bool isInitialized() const;
private:
bool _needSetup;
void InitializeInstanceFields();
};
} // namespace antlr4
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#include "CharStream.h"
using namespace antlr4;
CharStream::~CharStream() {}
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#pragma once
#include "IntStream.h"
#include "misc/Interval.h"
namespace antlr4 {
/// A source of characters for an ANTLR lexer.
class ANTLR4CPP_PUBLIC CharStream : public IntStream {
public:
virtual ~CharStream();
/// This method returns the text for a range of characters within this input
/// stream. This method is guaranteed to not throw an exception if the
/// specified interval lies entirely within a marked range. For more
/// information about marked ranges, see IntStream::mark.
///
/// <param name="interval"> an interval within the stream </param>
/// <returns> the text of the specified interval
/// </returns>
/// <exception cref="NullPointerException"> if {@code interval} is {@code
/// null} </exception> <exception cref="IllegalArgumentException"> if {@code
/// interval.a < 0}, or if
/// {@code interval.b < interval.a - 1}, or if {@code interval.b} lies at or
/// past the end of the stream </exception>
/// <exception cref="UnsupportedOperationException"> if the stream does not
/// support getting the text of the specified interval </exception>
virtual std::string getText(const misc::Interval& interval) = 0;
virtual std::string toString() const = 0;
};
} // namespace antlr4
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#include "CharStream.h"
#include "Recognizer.h"
#include "TokenSource.h"
#include "Vocabulary.h"
#include "misc/Interval.h"
#include "support/CPPUtils.h"
#include "support/StringUtils.h"
#include "CommonToken.h"
using namespace antlr4;
using namespace antlr4::misc;
using namespace antlrcpp;
const std::pair<TokenSource*, CharStream*> CommonToken::EMPTY_SOURCE(nullptr,
nullptr);
CommonToken::CommonToken(size_t type) {
InitializeInstanceFields();
_type = type;
}
CommonToken::CommonToken(std::pair<TokenSource*, CharStream*> source,
size_t type, size_t channel, size_t start,
size_t stop) {
InitializeInstanceFields();
_source = source;
_type = type;
_channel = channel;
_start = start;
_stop = stop;
if (_source.first != nullptr) {
_line = static_cast<int>(source.first->getLine());
_charPositionInLine = source.first->getCharPositionInLine();
}
}
CommonToken::CommonToken(size_t type, const std::string& text) {
InitializeInstanceFields();
_type = type;
_channel = DEFAULT_CHANNEL;
_text = text;
_source = EMPTY_SOURCE;
}
CommonToken::CommonToken(Token* oldToken) {
InitializeInstanceFields();
_type = oldToken->getType();
_line = oldToken->getLine();
_index = oldToken->getTokenIndex();
_charPositionInLine = oldToken->getCharPositionInLine();
_channel = oldToken->getChannel();
_start = oldToken->getStartIndex();
_stop = oldToken->getStopIndex();
if (is<CommonToken*>(oldToken)) {
_text = (static_cast<CommonToken*>(oldToken))->_text;
_source = (static_cast<CommonToken*>(oldToken))->_source;
} else {
_text = oldToken->getText();
_source = {oldToken->getTokenSource(), oldToken->getInputStream()};
}
}
size_t CommonToken::getType() const { return _type; }
void CommonToken::setLine(size_t line) { _line = line; }
std::string CommonToken::getText() const {
if (!_text.empty()) {
return _text;
}
CharStream* input = getInputStream();
if (input == nullptr) {
return "";
}
size_t n = input->size();
if (_start < n && _stop < n) {
return input->getText(misc::Interval(_start, _stop));
} else {
return "<EOF>";
}
}
void CommonToken::setText(const std::string& text) { _text = text; }
size_t CommonToken::getLine() const { return _line; }
size_t CommonToken::getCharPositionInLine() const {
return _charPositionInLine;
}
void CommonToken::setCharPositionInLine(size_t charPositionInLine) {
_charPositionInLine = charPositionInLine;
}
size_t CommonToken::getChannel() const { return _channel; }
void CommonToken::setChannel(size_t channel) { _channel = channel; }
void CommonToken::setType(size_t type) { _type = type; }
size_t CommonToken::getStartIndex() const { return _start; }
void CommonToken::setStartIndex(size_t start) { _start = start; }
size_t CommonToken::getStopIndex() const { return _stop; }
void CommonToken::setStopIndex(size_t stop) { _stop = stop; }
size_t CommonToken::getTokenIndex() const { return _index; }
void CommonToken::setTokenIndex(size_t index) { _index = index; }
antlr4::TokenSource* CommonToken::getTokenSource() const {
return _source.first;
}
antlr4::CharStream* CommonToken::getInputStream() const {
return _source.second;
}
std::string CommonToken::toString() const { return toString(nullptr); }
std::string CommonToken::toString(Recognizer* r) const {
std::stringstream ss;
std::string channelStr;
if (_channel > 0) {
channelStr = ",channel=" + std::to_string(_channel);
}
std::string txt = getText();
if (!txt.empty()) {
antlrcpp::replaceAll(txt, "\n", "\\n");
antlrcpp::replaceAll(txt, "\r", "\\r");
antlrcpp::replaceAll(txt, "\t", "\\t");
} else {
txt = "<no text>";
}
std::string typeString = std::to_string(symbolToNumeric(_type));
if (r != nullptr) typeString = r->getVocabulary().getDisplayName(_type);
ss << "[@" << symbolToNumeric(getTokenIndex()) << ","
<< symbolToNumeric(_start) << ":" << symbolToNumeric(_stop) << "='" << txt
<< "',<" << typeString << ">" << channelStr << "," << _line << ":"
<< getCharPositionInLine() << "]";
return ss.str();
}
void CommonToken::InitializeInstanceFields() {
_type = 0;
_line = 0;
_charPositionInLine = INVALID_INDEX;
_channel = DEFAULT_CHANNEL;
_index = INVALID_INDEX;
_start = 0;
_stop = 0;
_source = EMPTY_SOURCE;
}
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#pragma once
#include "WritableToken.h"
namespace antlr4 {
class ANTLR4CPP_PUBLIC CommonToken : public WritableToken {
protected:
/**
* An empty {@link Pair} which is used as the default value of
* {@link #source} for tokens that do not have a source.
*/
static const std::pair<TokenSource*, CharStream*> EMPTY_SOURCE;
/**
* This is the backing field for {@link #getType} and {@link #setType}.
*/
size_t _type;
/**
* This is the backing field for {@link #getLine} and {@link #setLine}.
*/
size_t _line;
/**
* This is the backing field for {@link #getCharPositionInLine} and
* {@link #setCharPositionInLine}.
*/
size_t _charPositionInLine; // set to invalid position
/**
* This is the backing field for {@link #getChannel} and
* {@link #setChannel}.
*/
size_t _channel;
/**
* This is the backing field for {@link #getTokenSource} and
* {@link #getInputStream}.
*
* <p>
* These properties share a field to reduce the memory footprint of
* {@link CommonToken}. Tokens created by a {@link CommonTokenFactory} from
* the same source and input stream share a reference to the same
* {@link Pair} containing these values.</p>
*/
std::pair<TokenSource*, CharStream*> _source; // ml: pure references, usually
// from statically allocated
// classes.
/**
* This is the backing field for {@link #getText} when the token text is
* explicitly set in the constructor or via {@link #setText}.
*
* @see #getText()
*/
std::string _text;
/**
* This is the backing field for {@link #getTokenIndex} and
* {@link #setTokenIndex}.
*/
size_t _index;
/**
* This is the backing field for {@link #getStartIndex} and
* {@link #setStartIndex}.
*/
size_t _start;
/**
* This is the backing field for {@link #getStopIndex} and
* {@link #setStopIndex}.
*/
size_t _stop;
public:
/**
* Constructs a new {@link CommonToken} with the specified token type.
*
* @param type The token type.
*/
CommonToken(size_t type);
CommonToken(std::pair<TokenSource*, CharStream*> source, size_t type,
size_t channel, size_t start, size_t stop);
/**
* Constructs a new {@link CommonToken} with the specified token type and
* text.
*
* @param type The token type.
* @param text The text of the token.
*/
CommonToken(size_t type, const std::string& text);
/**
* Constructs a new {@link CommonToken} as a copy of another {@link Token}.
*
* <p>
* If {@code oldToken} is also a {@link CommonToken} instance, the newly
* constructed token will share a reference to the {@link #text} field and
* the {@link Pair} stored in {@link #source}. Otherwise, {@link #text} will
* be assigned the result of calling {@link #getText}, and {@link #source}
* will be constructed from the result of {@link Token#getTokenSource} and
* {@link Token#getInputStream}.</p>
*
* @param oldToken The token to copy.
*/
CommonToken(Token* oldToken);
virtual size_t getType() const override;
/**
* Explicitly set the text for this token. If {code text} is not
* {@code null}, then {@link #getText} will return this value rather than
* extracting the text from the input.
*
* @param text The explicit text of the token, or {@code null} if the text
* should be obtained from the input along with the start and stop indexes
* of the token.
*/
virtual void setText(const std::string& text) override;
virtual std::string getText() const override;
virtual void setLine(size_t line) override;
virtual size_t getLine() const override;
virtual size_t getCharPositionInLine() const override;
virtual void setCharPositionInLine(size_t charPositionInLine) override;
virtual size_t getChannel() const override;
virtual void setChannel(size_t channel) override;
virtual void setType(size_t type) override;
virtual size_t getStartIndex() const override;
virtual void setStartIndex(size_t start);
virtual size_t getStopIndex() const override;
virtual void setStopIndex(size_t stop);
virtual size_t getTokenIndex() const override;
virtual void setTokenIndex(size_t index) override;
virtual TokenSource* getTokenSource() const override;
virtual CharStream* getInputStream() const override;
virtual std::string toString() const override;
virtual std::string toString(Recognizer* r) const;
private:
void InitializeInstanceFields();
};
} // namespace antlr4
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#include "CharStream.h"
#include "CommonToken.h"
#include "misc/Interval.h"
#include "CommonTokenFactory.h"
using namespace antlr4;
const Ref<TokenFactory<CommonToken>> CommonTokenFactory::DEFAULT =
std::make_shared<CommonTokenFactory>();
CommonTokenFactory::CommonTokenFactory(bool copyText_) : copyText(copyText_) {}
CommonTokenFactory::CommonTokenFactory() : CommonTokenFactory(false) {}
std::unique_ptr<CommonToken> CommonTokenFactory::create(
std::pair<TokenSource*, CharStream*> source, size_t type,
const std::string& text, size_t channel, size_t start, size_t stop,
size_t line, size_t charPositionInLine) {
std::unique_ptr<CommonToken> t(
new CommonToken(source, type, channel, start, stop));
t->setLine(line);
t->setCharPositionInLine(charPositionInLine);
if (text != "") {
t->setText(text);
} else if (copyText && source.second != nullptr) {
t->setText(source.second->getText(misc::Interval(start, stop)));
}
return t;
}
std::unique_ptr<CommonToken> CommonTokenFactory::create(
size_t type, const std::string& text) {
return std::unique_ptr<CommonToken>(new CommonToken(type, text));
}
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#pragma once
#include "TokenFactory.h"
namespace antlr4 {
/**
* This default implementation of {@link TokenFactory} creates
* {@link CommonToken} objects.
*/
class ANTLR4CPP_PUBLIC CommonTokenFactory : public TokenFactory<CommonToken> {
public:
/**
* The default {@link CommonTokenFactory} instance.
*
* <p>
* This token factory does not explicitly copy token text when constructing
* tokens.</p>
*/
static const Ref<TokenFactory<CommonToken>> DEFAULT;
protected:
/**
* Indicates whether {@link CommonToken#setText} should be called after
* constructing tokens to explicitly set the text. This is useful for cases
* where the input stream might not be able to provide arbitrary substrings
* of text from the input after the lexer creates a token (e.g. the
* implementation of {@link CharStream#getText} in
* {@link UnbufferedCharStream} throws an
* {@link UnsupportedOperationException}). Explicitly setting the token text
* allows {@link Token#getText} to be called at any time regardless of the
* input stream implementation.
*
* <p>
* The default value is {@code false} to avoid the performance and memory
* overhead of copying text for every token unless explicitly requested.</p>
*/
const bool copyText;
public:
/**
* Constructs a {@link CommonTokenFactory} with the specified value for
* {@link #copyText}.
*
* <p>
* When {@code copyText} is {@code false}, the {@link #DEFAULT} instance
* should be used instead of constructing a new instance.</p>
*
* @param copyText The value for {@link #copyText}.
*/
CommonTokenFactory(bool copyText);
/**
* Constructs a {@link CommonTokenFactory} with {@link #copyText} set to
* {@code false}.
*
* <p>
* The {@link #DEFAULT} instance should be used instead of calling this
* directly.</p>
*/
CommonTokenFactory();
virtual std::unique_ptr<CommonToken> create(
std::pair<TokenSource*, CharStream*> source, size_t type,
const std::string& text, size_t channel, size_t start, size_t stop,
size_t line, size_t charPositionInLine) override;
virtual std::unique_ptr<CommonToken> create(size_t type,
const std::string& text) override;
};
} // namespace antlr4
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#include "Token.h"
#include "CommonTokenStream.h"
using namespace antlr4;
CommonTokenStream::CommonTokenStream(TokenSource* tokenSource)
: CommonTokenStream(tokenSource, Token::DEFAULT_CHANNEL) {}
CommonTokenStream::CommonTokenStream(TokenSource* tokenSource, size_t channel_)
: BufferedTokenStream(tokenSource), channel(channel_) {}
ssize_t CommonTokenStream::adjustSeekIndex(size_t i) {
return nextTokenOnChannel(i, channel);
}
Token* CommonTokenStream::LB(size_t k) {
if (k == 0 || k > _p) {
return nullptr;
}
ssize_t i = static_cast<ssize_t>(_p);
size_t n = 1;
// find k good tokens looking backwards
while (n <= k) {
// skip off-channel tokens
i = previousTokenOnChannel(i - 1, channel);
n++;
}
if (i < 0) {
return nullptr;
}
return _tokens[i].get();
}
Token* CommonTokenStream::LT(ssize_t k) {
lazyInit();
if (k == 0) {
return nullptr;
}
if (k < 0) {
return LB(static_cast<size_t>(-k));
}
size_t i = _p;
ssize_t n = 1; // we know tokens[p] is a good one
// find k good tokens
while (n < k) {
// skip off-channel tokens, but make sure to not look past EOF
if (sync(i + 1)) {
i = nextTokenOnChannel(i + 1, channel);
}
n++;
}
return _tokens[i].get();
}
int CommonTokenStream::getNumberOfOnChannelTokens() {
int n = 0;
fill();
for (size_t i = 0; i < _tokens.size(); i++) {
Token* t = _tokens[i].get();
if (t->getChannel() == channel) {
n++;
}
if (t->getType() == Token::EOF) {
break;
}
}
return n;
}
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#pragma once
#include "BufferedTokenStream.h"
namespace antlr4 {
/**
* This class extends {@link BufferedTokenStream} with functionality to filter
* token streams to tokens on a particular channel (tokens where
* {@link Token#getChannel} returns a particular value).
*
* <p>
* This token stream provides access to all tokens by index or when calling
* methods like {@link #getText}. The channel filtering is only used for code
* accessing tokens via the lookahead methods {@link #LA}, {@link #LT}, and
* {@link #LB}.</p>
*
* <p>
* By default, tokens are placed on the default channel
* ({@link Token#DEFAULT_CHANNEL}), but may be reassigned by using the
* {@code ->channel(HIDDEN)} lexer command, or by using an embedded action to
* call {@link Lexer#setChannel}.
* </p>
*
* <p>
* Note: lexer rules which use the {@code ->skip} lexer command or call
* {@link Lexer#skip} do not produce tokens at all, so input text matched by
* such a rule will not be available as part of the token stream, regardless of
* channel.</p>
*/
class ANTLR4CPP_PUBLIC CommonTokenStream : public BufferedTokenStream {
public:
/**
* Constructs a new {@link CommonTokenStream} using the specified token
* source and the default token channel ({@link Token#DEFAULT_CHANNEL}).
*
* @param tokenSource The token source.
*/
CommonTokenStream(TokenSource* tokenSource);
/**
* Constructs a new {@link CommonTokenStream} using the specified token
* source and filtering tokens to the specified channel. Only tokens whose
* {@link Token#getChannel} matches {@code channel} or have the
* {@link Token#getType} equal to {@link Token#EOF} will be returned by the
* token stream lookahead methods.
*
* @param tokenSource The token source.
* @param channel The channel to use for filtering tokens.
*/
CommonTokenStream(TokenSource* tokenSource, size_t channel);
virtual Token* LT(ssize_t k) override;
/// Count EOF just once.
virtual int getNumberOfOnChannelTokens();
protected:
/**
* Specifies the channel to use for filtering tokens.
*
* <p>
* The default value is {@link Token#DEFAULT_CHANNEL}, which matches the
* default channel assigned to tokens created by the lexer.</p>
*/
size_t channel;
virtual ssize_t adjustSeekIndex(size_t i) override;
virtual Token* LB(size_t k) override;
};
} // namespace antlr4
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#include "ConsoleErrorListener.h"
using namespace antlr4;
ConsoleErrorListener ConsoleErrorListener::INSTANCE;
void ConsoleErrorListener::syntaxError(Recognizer* /*recognizer*/,
Token* /*offendingSymbol*/, size_t line,
size_t charPositionInLine,
const std::string& msg,
std::exception_ptr /*e*/) {
std::cerr << "line " << line << ":" << charPositionInLine << " " << msg
<< std::endl;
}
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#pragma once
#include "BaseErrorListener.h"
namespace antlr4 {
class ANTLR4CPP_PUBLIC ConsoleErrorListener : public BaseErrorListener {
public:
/**
* Provides a default instance of {@link ConsoleErrorListener}.
*/
static ConsoleErrorListener INSTANCE;
/**
* {@inheritDoc}
*
* <p>
* This implementation prints messages to {@link System#err} containing the
* values of {@code line}, {@code charPositionInLine}, and {@code msg} using
* the following format.</p>
*
* <pre>
* line <em>line</em>:<em>charPositionInLine</em> <em>msg</em>
* </pre>
*/
virtual void syntaxError(Recognizer* recognizer, Token* offendingSymbol,
size_t line, size_t charPositionInLine,
const std::string& msg,
std::exception_ptr e) override;
};
} // namespace antlr4
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#include "Parser.h"
#include "atn/ATNConfig.h"
#include "atn/ATNConfigSet.h"
#include "atn/PredictionContext.h"
#include "dfa/DFA.h"
#include "misc/Interval.h"
#include "DiagnosticErrorListener.h"
using namespace antlr4;
DiagnosticErrorListener::DiagnosticErrorListener()
: DiagnosticErrorListener(true) {}
DiagnosticErrorListener::DiagnosticErrorListener(bool exactOnly_)
: exactOnly(exactOnly_) {}
void DiagnosticErrorListener::reportAmbiguity(Parser* recognizer,
const dfa::DFA& dfa,
size_t startIndex,
size_t stopIndex, bool exact,
const antlrcpp::BitSet& ambigAlts,
atn::ATNConfigSet* configs) {
if (exactOnly && !exact) {
return;
}
std::string decision = getDecisionDescription(recognizer, dfa);
antlrcpp::BitSet conflictingAlts = getConflictingAlts(ambigAlts, configs);
std::string text = recognizer->getTokenStream()->getText(
misc::Interval(startIndex, stopIndex));
std::string message = "reportAmbiguity d=" + decision +
": ambigAlts=" + conflictingAlts.toString() +
", input='" + text + "'";
recognizer->notifyErrorListeners(message);
}
void DiagnosticErrorListener::reportAttemptingFullContext(
Parser* recognizer, const dfa::DFA& dfa, size_t startIndex,
size_t stopIndex, const antlrcpp::BitSet& /*conflictingAlts*/,
atn::ATNConfigSet* /*configs*/) {
std::string decision = getDecisionDescription(recognizer, dfa);
std::string text = recognizer->getTokenStream()->getText(
misc::Interval(startIndex, stopIndex));
std::string message =
"reportAttemptingFullContext d=" + decision + ", input='" + text + "'";
recognizer->notifyErrorListeners(message);
}
void DiagnosticErrorListener::reportContextSensitivity(
Parser* recognizer, const dfa::DFA& dfa, size_t startIndex,
size_t stopIndex, size_t /*prediction*/, atn::ATNConfigSet* /*configs*/) {
std::string decision = getDecisionDescription(recognizer, dfa);
std::string text = recognizer->getTokenStream()->getText(
misc::Interval(startIndex, stopIndex));
std::string message =
"reportContextSensitivity d=" + decision + ", input='" + text + "'";
recognizer->notifyErrorListeners(message);
}
std::string DiagnosticErrorListener::getDecisionDescription(
Parser* recognizer, const dfa::DFA& dfa) {
size_t decision = dfa.decision;
size_t ruleIndex =
(reinterpret_cast<atn::ATNState*>(dfa.atnStartState))->ruleIndex;
const std::vector<std::string>& ruleNames = recognizer->getRuleNames();
if (ruleIndex == INVALID_INDEX || ruleIndex >= ruleNames.size()) {
return std::to_string(decision);
}
std::string ruleName = ruleNames[ruleIndex];
if (ruleName == "" || ruleName.empty()) {
return std::to_string(decision);
}
return std::to_string(decision) + " (" + ruleName + ")";
}
antlrcpp::BitSet DiagnosticErrorListener::getConflictingAlts(
const antlrcpp::BitSet& reportedAlts, atn::ATNConfigSet* configs) {
if (reportedAlts.count() > 0) { // Not exactly like the original Java code,
// but this listener is only used in the
// TestRig (where it never provides a good
// alt set), so it's probably ok so.
return reportedAlts;
}
antlrcpp::BitSet result;
for (auto& config : configs->configs) {
result.set(config->alt);
}
return result;
}
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#include "Exceptions.h"
using namespace antlr4;
RuntimeException::RuntimeException(const std::string& msg)
: std::exception(), _message(msg) {}
const char* RuntimeException::what() const NOEXCEPT { return _message.c_str(); }
//------------------ IOException
//---------------------------------------------------------------------------------------
IOException::IOException(const std::string& msg)
: std::exception(), _message(msg) {}
const char* IOException::what() const NOEXCEPT { return _message.c_str(); }
//------------------ IllegalStateException
//-----------------------------------------------------------------------------
IllegalStateException::~IllegalStateException() {}
//------------------ IllegalArgumentException
//--------------------------------------------------------------------------
IllegalArgumentException::~IllegalArgumentException() {}
//------------------ NullPointerException
//------------------------------------------------------------------------------
NullPointerException::~NullPointerException() {}
//------------------ IndexOutOfBoundsException
//-------------------------------------------------------------------------
IndexOutOfBoundsException::~IndexOutOfBoundsException() {}
//------------------ UnsupportedOperationException
//---------------------------------------------------------------------
UnsupportedOperationException::~UnsupportedOperationException() {}
//------------------ EmptyStackException
//-------------------------------------------------------------------------------
EmptyStackException::~EmptyStackException() {}
//------------------ CancellationException
//-----------------------------------------------------------------------------
CancellationException::~CancellationException() {}
//------------------ ParseCancellationException
//------------------------------------------------------------------------
ParseCancellationException::~ParseCancellationException() {}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#include "Token.h"
antlr4::Token::~Token() {}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment