diff --git a/.travis.yml b/.travis.yml index 2897de583..335b5d3e1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -151,32 +151,32 @@ matrix: - os: linux jdk: openjdk7 env: TARGET=csharp - stage: extended-test + stage: main-test - os: linux jdk: oraclejdk8 dist: trusty env: - TARGET=dotnet - GROUP=LEXER - stage: main-test + stage: extended-test - os: linux jdk: openjdk8 dist: trusty env: - TARGET=dotnet - GROUP=PARSER - stage: main-test + stage: extended-test - os: linux jdk: oraclejdk8 dist: trusty env: - TARGET=dotnet - GROUP=RECURSION - stage: main-test + stage: extended-test - os: linux jdk: openjdk7 env: TARGET=python2 - stage: extended-test + stage: main-test - os: linux jdk: openjdk7 env: TARGET=python3 @@ -185,7 +185,7 @@ matrix: sources: - deadsnakes # source required so it finds the package definition below packages: - - python3.5 + - python3.6 stage: main-test - os: linux dist: trusty diff --git a/README.md b/README.md index efa018143..d63bc4f66 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # ANTLR v4 -[![Build Travis-CI Status](https://travis-ci.org/antlr/antlr4.png?branch=master)](https://travis-ci.org/antlr/antlr4) [![Build AppVeyor Status](https://ci.appveyor.com/api/projects/status/5acpbx1pg7bhgh8v/branch/master?svg=true)](https://ci.appveyor.com/project/parrt/antlr4) [![Java 7+](https://img.shields.io/badge/java-7+-4c7e9f.svg)](http://java.oracle.com) [![License](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/antlr/antlr4/master/LICENSE.txt) +[![Build Travis-CI Status](https://travis-ci.org/antlr/antlr4.svg?branch=master)](https://travis-ci.org/antlr/antlr4) [![Build AppVeyor Status](https://ci.appveyor.com/api/projects/status/5acpbx1pg7bhgh8v/branch/master?svg=true)](https://ci.appveyor.com/project/parrt/antlr4) [![Java 7+](https://img.shields.io/badge/java-7+-4c7e9f.svg)](http://java.oracle.com) [![License](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/antlr/antlr4/master/LICENSE.txt) **ANTLR** (ANother Tool for Language Recognition) is a powerful parser generator for reading, processing, executing, or translating structured text or binary files. It's widely used to build languages, tools, and frameworks. From a grammar, ANTLR generates a parser that can build parse trees and also generates a listener interface (or visitor) that makes it easy to respond to the recognition of phrases of interest. diff --git a/contributors.txt b/contributors.txt index 394adc60d..20bfeb9a4 100644 --- a/contributors.txt +++ b/contributors.txt @@ -178,5 +178,27 @@ YYYY/MM/DD, github id, Full name, email 2017/12/01, DavidMoraisFerreira, David Morais Ferreira, david.moraisferreira@gmail.com 2017/12/01, SebastianLng, Sebastian Lang, sebastian.lang@outlook.com 2017/12/03, oranoran, Oran Epelbaum, oran / epelbaum me +2017/12/12, janlinde, Jan Lindemann, jan@janware.com +2017/12/13, enessoylu, Enes Soylu, enessoylutr@gmail.com +2017/12/20, kbsletten, Kyle Sletten, kbsletten@gmail.com 2017/12/27, jkmar, Jakub Marciniszyn, marciniszyn.jk@gmail.com +2018/01/06, kasbah, Kaspar Emanuel, kaspar@monostable.co.uk 2018/01/15, xgcssch, Sönke Schau, xgcssch@users.noreply.github.com +2018/02/08, razfriman, Raz Friman, raz@razfriman.com +2018/02/11, io7m, Mark Raynsford, code@io7m.com +2018/15/05, johnvanderholt, jan dillingh johnvanderholte@gmail.com +2018/06/16, EternalPhane, Zongyuan Zuo, eternalphane@gmail.com +2018/06/27, wu-sheng, Wu Sheng, wu.sheng@foxmail.com +2018/02/25, chaseoxide, Marcus Ong, taccs97[at]gmail[dot]com +2018/05/15, johnvanderholt, jan dillingh johnvanderholte@gmail.com +2018/06/16, EternalPhane, Zongyuan Zuo, eternalphane@gmail.com +2018/05/15, johnvanderholt, jan dillingh johnvanderholte@gmail.com +2018/05/17, sinopsysHK, Eric Bardes, sinofwd@gmail.com +2018/05/23, srvance, Stephen Vance, steve@vance.com +2018/06/14, alecont, Alessandro Contenti, alecontenti@hotmail.com +2018/06/16, EternalPhane, Zongyuan Zuo, eternalphane@gmail.com +2018/07/03, jgoppert, James Goppert, james.goppert@gmail.com +2018/07/27, Maksim Novikov, mnovikov.work@gmail.com +2018/07/31 Lucas Henrqiue, lucashenrique580@gmail.com +2018/08/03, ENDOH takanao, djmchl@gmail.com +2018/10/29, chrisaycock, Christopher Aycock, chris[at]chrisaycock[dot]com diff --git a/doc/antlr-project-testing.md b/doc/antlr-project-testing.md index 335f2da2b..1ff46aae9 100644 --- a/doc/antlr-project-testing.md +++ b/doc/antlr-project-testing.md @@ -42,9 +42,9 @@ In order to perform the tests on all target languages, you need to have the foll * `mono` (e.g., `brew install mono`) on non-Windows boxes (on Windows it uses the Microsoft .net stack). Also must [`xbuild` the runtime](https://github.com/antlr/antlr4/blob/master/doc/releasing-antlr.md) before tests will run; see below * `nodejs` * Python 2.7 -* Python 3.5 +* Python 3.6 * Go -* Swift 3 (via XCode 8.x) tested currently only osx +* Swift 4 (via XCode 10.x) tested currently only osx * clang (for C++ target) * To **install into local repository** `~/.m2/repository/org/antlr`, do this: diff --git a/doc/building-antlr.md b/doc/building-antlr.md index 06f1ace56..494bea81d 100644 --- a/doc/building-antlr.md +++ b/doc/building-antlr.md @@ -28,16 +28,7 @@ Checking out files: 100% (1427/1427), done. # Compile ```bash -$ cd /tmp -$ git clone git@github.com:antlr/antlr4.git -Cloning into 'antlr4'... -remote: Counting objects: 59858, done. -remote: Compressing objects: 100% (57/57), done. -remote: Total 59858 (delta 28), reused 9 (delta 9), pack-reused 59786 -Receiving objects: 100% (59858/59858), 31.10 MiB | 819.00 KiB/s, done. -Resolving deltas: 100% (31898/31898), done. -Checking connectivity... done. -$ cd antlr4 +$ cd /tmp/antlr4 $ export MAVEN_OPTS="-Xmx1G" # don't forget this on linux $ mvn clean # must be separate, not part of install/compile $ mvn -DskipTests install diff --git a/doc/csharp-target.md b/doc/csharp-target.md index 9158b0211..40be51840 100644 --- a/doc/csharp-target.md +++ b/doc/csharp-target.md @@ -21,7 +21,7 @@ You will find full instructions on the [Git repo page for ANTLR C# runtime](http Let's suppose that your grammar is named `MyGrammar`. The tool will generate for you the following files: -* MyGrammarLexer.cs +* MyGrammarLexer.cs * MyGrammarParser.cs * MyGrammarListener.cs (if you have not activated the -no-listener option) * MyGrammarBaseListener.cs (if you have not activated the -no-listener option) @@ -32,6 +32,7 @@ Now a fully functioning code might look like the following for start rule `Start ``` using Antlr4.Runtime; +using Antlr4.Runtime.Tree; public void MyParseMethod() { String input = "your text to parse here"; @@ -39,7 +40,7 @@ public void MyParseMethod() { ITokenSource lexer = new MyGrammarLexer(stream); ITokenStream tokens = new CommonTokenStream(lexer); MyGrammarParser parser = new MyGrammarParser(tokens); - parser.buildParseTrees = true; + parser.BuildParseTree = true; IParseTree tree = parser.StartRule(); } ``` diff --git a/doc/getting-started.md b/doc/getting-started.md index dabd8c19d..add563579 100644 --- a/doc/getting-started.md +++ b/doc/getting-started.md @@ -31,7 +31,7 @@ It's also a good idea to put this in your `.bash_profile` or whatever your start 3. Create aliases for the ANTLR Tool, and `TestRig`. ``` $ alias antlr4='java -Xmx500M -cp "/usr/local/lib/antlr-4.7.1-complete.jar:$CLASSPATH" org.antlr.v4.Tool' -$ alias grun='java org.antlr.v4.gui.TestRig' +$ alias grun='java -Xmx500M -cp "/usr/local/lib/antlr-4.7.1-complete.jar:$CLASSPATH" org.antlr.v4.gui.TestRig' ``` ### WINDOWS diff --git a/doc/java-target.md b/doc/java-target.md index f6e615482..60612a9fd 100644 --- a/doc/java-target.md +++ b/doc/java-target.md @@ -16,7 +16,7 @@ Also, I have prepared a [video](https://youtu.be/eW4WFgRtFeY) that will help you ### Eclipse -Edgar Espina has created an [eclipse plugin for ANTLR v4](https://youtu.be/eW4WFgRtFeY). Features: Advanced Syntax Highlighting, Automatic Code Generation (on save), Manual Code Generation (through External Tools menu), Code Formatter (Ctrl+Shift+F), Syntax Diagrams, Advanced Rule Navigation between files (F3), Quick fixes. +Edgar Espina has created an [eclipse plugin for ANTLR v4](https://marketplace.eclipse.org/content/antlr-ide). Features: Advanced Syntax Highlighting, Automatic Code Generation (on save), Manual Code Generation (through External Tools menu), Code Formatter (Ctrl+Shift+F), Syntax Diagrams, Advanced Rule Navigation between files (F3), Quick fixes. ### NetBeans @@ -241,4 +241,4 @@ mvn install mvn exec:java -Dexec.mainClass=org.abcd.examples.ArrayInit.ArrayInit {1,2,3} ^D -``` \ No newline at end of file +``` diff --git a/doc/javascript-target.md b/doc/javascript-target.md index 3473e95b5..2d9973be6 100644 --- a/doc/javascript-target.md +++ b/doc/javascript-target.md @@ -62,7 +62,7 @@ The steps to create your parsing code are the following: You are now ready to bundle your parsing code as follows: - following webpack specs, create a webpack.config file - in the webpack.config file, exclude node.js only modules using: node: { module: "empty", net: "empty", fs: "empty" } - - from the cmd line, nag-vigate to the directory containing webpack.config and type: webpack + - from the cmd line, navigate to the directory containing webpack.config and type: webpack This will produce a single js file containing all your parsing code. Easy to include in your web pages! @@ -95,11 +95,16 @@ Let's suppose that your grammar is named, as above, "MyGrammar". Let's suppose t Now a fully functioning script might look like the following: ```javascript + var antlr4 = require('antlr4'); + var MyGrammarLexer = require('./MyGrammarLexer').MyGrammarLexer; + var MyGrammarParser = require('./MyGrammarParser').MyGrammarParser; + var MyGrammarListener = require('./MyGrammarListener').MyGrammarListener; + var input = "your text to parse here" var chars = new antlr4.InputStream(input); - var lexer = new MyGrammarLexer.MyGrammarLexer(chars); + var lexer = new MyGrammarLexer(chars); var tokens = new antlr4.CommonTokenStream(lexer); - var parser = new MyGrammarParser.MyGrammarParser(tokens); + var parser = new MyGrammarParser(tokens); parser.buildParseTrees = true; var tree = parser.MyStartRule(); ``` @@ -128,30 +133,30 @@ Let's suppose your MyGrammar grammar comprises 2 rules: "key" and "value". The a ``` In order to provide custom behavior, you might want to create the following class: - + ```javascript - KeyPrinter = function() { - MyGrammarListener.call(this); // inherit default listener - return this; - }; - -// inherit default listener +var KeyPrinter = function() { + MyGrammarListener.call(this); // inherit default listener + return this; +}; + +// continue inheriting default listener KeyPrinter.prototype = Object.create(MyGrammarListener.prototype); KeyPrinter.prototype.constructor = KeyPrinter; - + // override default listener behavior - KeyPrinter.prototype.exitKey = function(ctx) { - console.log("Oh, a key!"); - }; +KeyPrinter.prototype.exitKey = function(ctx) { + console.log("Oh, a key!"); +}; ``` In order to execute this listener, you would simply add the following lines to the above code: - + ```javascript - ... - tree = parser.StartRule() - only repeated here for reference - var printer = new KeyPrinter(); - antlr4.tree.ParseTreeWalker.DEFAULT.walk(printer, tree); + ... + tree = parser.StartRule() // only repeated here for reference +var printer = new KeyPrinter(); +antlr4.tree.ParseTreeWalker.DEFAULT.walk(printer, tree); ``` ## What about TypeScript? diff --git a/doc/releasing-antlr.md b/doc/releasing-antlr.md index e3ed7915b..a44e48e7d 100644 --- a/doc/releasing-antlr.md +++ b/doc/releasing-antlr.md @@ -150,13 +150,13 @@ Uploaded: https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antl The maven deploy lifecycle phased deploys the artifacts and the poms for the ANTLR project to the [sonatype remote staging server](https://oss.sonatype.org/content/repositories/snapshots/). ```bash -mvn deploy -DskipTests +export JAVA_HOME=`/usr/libexec/java_home -v 1.7`; mvn deploy -DskipTests ``` With JDK 1.7 (not 6 or 8), do this: ```bash -mvn release:prepare -Darguments="-DskipTests" +export JAVA_HOME=`/usr/libexec/java_home -v 1.7`; mvn release:prepare -Darguments="-DskipTests" ``` Hm...per https://github.com/keybase/keybase-issues/issues/1712 we need this to make gpg work: @@ -172,6 +172,13 @@ alias java='/Library/Java/JavaVirtualMachines/jdk1.7.0_21.jdk/Contents/Home/bin/ alias javac='/Library/Java/JavaVirtualMachines/jdk1.7.0_21.jdk/Contents/Home/bin/javac' alias javadoc='/Library/Java/JavaVirtualMachines/jdk1.7.0_21.jdk/Contents/Home/bin/javadoc' alias jar='/Library/Java/JavaVirtualMachines/jdk1.7.0_21.jdk/Contents/Home/bin/jar' +export JAVA_HOME=`/usr/libexec/java_home -v 1.7` +``` + +But I think just this on front of mvn works: + +``` +export JAVA_HOME=`/usr/libexec/java_home -v 1.7`; mvn ... ``` You should see 0x33 in generated .class files after 0xCAFEBABE; see [Java SE 7 = 51 (0x33 hex)](https://en.wikipedia.org/wiki/Java_class_file): diff --git a/runtime-testsuite/pom.xml b/runtime-testsuite/pom.xml index b56ad37fc..04e7beff3 100644 --- a/runtime-testsuite/pom.xml +++ b/runtime-testsuite/pom.xml @@ -26,7 +26,7 @@ org.antlr ST4 - 4.0.8 + 4.1-SNAPSHOT test @@ -66,10 +66,10 @@ test - org.eclipse.jetty - jetty-server - 8.1.16.v20140903 - test + org.eclipse.jetty + jetty-server + [9.3.24.v20180605,) + test org.glassfish diff --git a/runtime-testsuite/test/org/antlr/v4/test/runtime/descriptors/ParserExecDescriptors.java b/runtime-testsuite/test/org/antlr/v4/test/runtime/descriptors/ParserExecDescriptors.java index 297d2989e..ca6e393dd 100644 --- a/runtime-testsuite/test/org/antlr/v4/test/runtime/descriptors/ParserExecDescriptors.java +++ b/runtime-testsuite/test/org/antlr/v4/test/runtime/descriptors/ParserExecDescriptors.java @@ -854,4 +854,39 @@ public class ParserExecDescriptors { @CommentHasStringValue public String grammar; } + + /** + * This is a regression test for antlr/antlr4#2301. + */ + public static class OrderingPredicates extends BaseParserTestDescriptor { + public String input = "POINT AT X"; + public String output = null; + public String errors = null; + public String startRule = "expr"; + public String grammarName = "Issue2301"; + + /** + grammar Issue2301; + + SPACES: [ \t\r\n]+ -> skip; + + AT: 'AT'; + X : 'X'; + Y : 'Y'; + + ID: [A-Z]+; + + constant + : 'DUMMY' + ; + + expr + : ID constant? + | expr AT X + | expr AT Y + ; + */ + @CommentHasStringValue + public String grammar; + } } diff --git a/runtime-testsuite/test/org/antlr/v4/test/runtime/python/BasePythonTest.java b/runtime-testsuite/test/org/antlr/v4/test/runtime/python/BasePythonTest.java index dae677102..06cbfa1af 100644 --- a/runtime-testsuite/test/org/antlr/v4/test/runtime/python/BasePythonTest.java +++ b/runtime-testsuite/test/org/antlr/v4/test/runtime/python/BasePythonTest.java @@ -514,7 +514,10 @@ public abstract class BasePythonTest implements RuntimeTestSupport { } private String locateTool(String tool) { - String[] roots = { "/opt/local/bin", "/usr/bin/", "/usr/local/bin/" }; + String[] roots = { + "/opt/local/bin", "/usr/bin/", "/usr/local/bin/", + "/Users/"+System.getProperty("user.name")+"/anaconda3/bin/" + }; for(String root : roots) { if(new File(root + tool).exists()) { return root+tool; diff --git a/runtime-testsuite/test/org/antlr/v4/test/runtime/python3/BasePython3Test.java b/runtime-testsuite/test/org/antlr/v4/test/runtime/python3/BasePython3Test.java index e710de64f..f9e037fe8 100644 --- a/runtime-testsuite/test/org/antlr/v4/test/runtime/python3/BasePython3Test.java +++ b/runtime-testsuite/test/org/antlr/v4/test/runtime/python3/BasePython3Test.java @@ -19,8 +19,8 @@ public class BasePython3Test extends BasePythonTest { @Override protected String getPythonExecutable() { - return "python3.5"; - } // force 3.5 + return "python3.6"; + } // force 3.6 @Override protected void writeLexerTestFile(String lexerName, boolean showDFA) { diff --git a/runtime/CSharp/README.md b/runtime/CSharp/README.md index 265f2b4ee..3985a298b 100644 --- a/runtime/CSharp/README.md +++ b/runtime/CSharp/README.md @@ -51,7 +51,13 @@ This is just a quick start. The tool has many useful options to control generati The Antlr 4 standard runtime for C# is now available from NuGet. We trust that you know how to do add NuGet references to your project :-). -The package id is Antlr4.Runtime.Standard. We do not support other packages. +The package id is [Antlr4.Runtime.Standard](https://www.nuget.org/packages/Antlr4.Runtime.Standard/). We do not support other packages. + +Use the GUI or the following command in the Package Manager Console: + +``` +Install-Package Antlr4.Runtime.Standard +``` ### Step 6: You're done! diff --git a/runtime/Cpp/CMakeLists.txt b/runtime/Cpp/CMakeLists.txt index bb5d7fef4..b7ed65b29 100644 --- a/runtime/Cpp/CMakeLists.txt +++ b/runtime/Cpp/CMakeLists.txt @@ -20,6 +20,8 @@ if(NOT WITH_DEMO) endif(NOT WITH_DEMO) option(WITH_LIBCXX "Building with clang++ and libc++(in Linux). To enable with: -DWITH_LIBCXX=On" On) +option(WITH_STATIC_CRT "(Visual C++) Enable to statically link CRT, which avoids requiring users to install the redistribution package. + To disable with: -DWITH_STATIC_CRT=Off" On) project(LIBANTLR4) @@ -47,11 +49,11 @@ endif() file(STRINGS "VERSION" ANTLR_VERSION) -if (WITH_DEMO) +if(WITH_DEMO) # Java is not necessary if building without demos. find_package(Java COMPONENTS Runtime REQUIRED) - if (NOT ANTLR_JAR_LOCATION) + if(NOT ANTLR_JAR_LOCATION) message(FATAL_ERROR "Missing antlr4.jar location. You can specify it's path using: -DANTLR_JAR_LOCATION=") else() get_filename_component(ANTLR_NAME ${ANTLR_JAR_LOCATION} NAME_WE) @@ -63,7 +65,7 @@ if (WITH_DEMO) endif() endif(WITH_DEMO) -if (MSVC_VERSION) +if(MSVC_VERSION) set(MY_CXX_WARNING_FLAGS " /W4") else() set(MY_CXX_WARNING_FLAGS " -Wall -pedantic -W") @@ -82,7 +84,7 @@ else() endif() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MY_CXX_WARNING_FLAGS}") -if (MSVC_VERSION) +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}") @@ -95,34 +97,34 @@ else() endif() # Compiler-specific C++11 activation. -if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Intel") +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 header. (test in ubuntu) - if (NOT (GCC_VERSION VERSION_GREATER 5.0 OR GCC_VERSION VERSION_EQUAL 5.0)) + 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++") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -stdlib=libc++") elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND ( CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME MATCHES "FreeBSD") ) 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)) + 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 () + endif() # You can use libc++ to compile this project when g++ is NOT greater than or equal to 5.0. - if (WITH_LIBCXX) + if(WITH_LIBCXX) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") endif() -elseif ( MSVC_VERSION GREATER 1800 OR MSVC_VERSION EQUAL 1800 ) +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 () +endif() add_subdirectory(runtime) -if (WITH_DEMO) +if(WITH_DEMO) add_subdirectory(demo) endif(WITH_DEMO) @@ -179,14 +181,17 @@ configure_package_config_file( endif(ANTLR4_INSTALL) -if( EXISTS LICENSE.txt) - install(FILES LICENSE.txt - DESTINATION "share/doc/libantlr4") - elseif(EXISTS ../../LICENSE.txt) - install(FILES ../../LICENSE.txt - DESTINATION "share/doc/libantlr4") +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") +set(CPACK_PACKAGE_CONTACT "antlr-discussion@googlegroups.com") +set(CPACK_PACKAGE_VERSION ${ANTLR_VERSION}) +include(CPack) diff --git a/runtime/Cpp/cmake/ExternalAntlr4Cpp.cmake b/runtime/Cpp/cmake/ExternalAntlr4Cpp.cmake index fc926804e..ba540fcc3 100644 --- a/runtime/Cpp/cmake/ExternalAntlr4Cpp.cmake +++ b/runtime/Cpp/cmake/ExternalAntlr4Cpp.cmake @@ -1,223 +1,148 @@ -# -*- 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 3.7) -CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12.2) -PROJECT(antlr4cpp_fetcher CXX) -INCLUDE(ExternalProject) -FIND_PACKAGE(Git REQUIRED) +include(ExternalProject) -# 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}") +set(ANTLR4_ROOT ${CMAKE_CURRENT_BINARY_DIR}/antlr4_runtime/src/antlr4_runtime) +set(ANTLR4_INCLUDE_DIRS ${ANTLR4_ROOT}/runtime/Cpp/runtime/src) +set(ANTLR4_GIT_REPOSITORY https://github.com/antlr/antlr4.git) +if(NOT DEFINED ANTLR4_TAG) + # Set to branch name to keep library updated at the cost of needing to rebuild after 'clean' + # Set to commit hash to keep the build stable and does not need to rebuild after 'clean' + set(ANTLR4_TAG master) endif() -# default path for source files -if (NOT ANTLR4CPP_GENERATED_SRC_DIR) - set(ANTLR4CPP_GENERATED_SRC_DIR ${CMAKE_BINARY_DIR}/antlr4cpp_generated_src) +if(${CMAKE_GENERATOR} MATCHES "Visual Studio.*") + set(ANTLR4_OUTPUT_DIR ${ANTLR4_ROOT}/runtime/Cpp/dist/$(Configuration)) +elseif(${CMAKE_GENERATOR} MATCHES "Xcode.*") + set(ANTLR4_OUTPUT_DIR ${ANTLR4_ROOT}/runtime/Cpp/dist/$(CONFIGURATION)) +else() + set(ANTLR4_OUTPUT_DIR ${ANTLR4_ROOT}/runtime/Cpp/dist) 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 /scripts/CMakeLists.txt " -# #--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 /scripts/CMakeLists.txt " - #--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= -DCMAKE_SOURCE_DIR:PATH=/runtime/Cpp /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}") +if(MSVC) + set(ANTLR4_STATIC_LIBRARIES + ${ANTLR4_OUTPUT_DIR}/antlr4-runtime-static.lib) + set(ANTLR4_SHARED_LIBRARIES + ${ANTLR4_OUTPUT_DIR}/antlr4-runtime.lib) + set(ANTLR4_RUNTIME_LIBRARIES + ${ANTLR4_OUTPUT_DIR}/antlr4-runtime.dll) +else() + set(ANTLR4_STATIC_LIBRARIES + ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.a) + if(MINGW) + set(ANTLR4_SHARED_LIBRARIES + ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.dll.a) + set(ANTLR4_RUNTIME_LIBRARIES + ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.dll) + elseif(CYGWIN) + set(ANTLR4_SHARED_LIBRARIES + ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.dll.a) + set(ANTLR4_RUNTIME_LIBRARIES + ${ANTLR4_OUTPUT_DIR}/cygantlr4-runtime-4.7.1.dll) + elseif(APPLE) + set(ANTLR4_RUNTIME_LIBRARIES + ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.dylib) else() - message(FATAL_ERROR "Unable to find antlr tool. ANTLR4CPP_JAR_LOCATION:${ANTLR4CPP_JAR_LOCATION}") + set(ANTLR4_RUNTIME_LIBRARIES + ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.so) endif() +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}" - ) +if(${CMAKE_GENERATOR} MATCHES ".* Makefiles") + # This avoids + # 'warning: jobserver unavailable: using -j1. Add '+' to parent make rule.' + set(ANTLR4_BUILD_COMMAND $(MAKE)) +elseif(${CMAKE_GENERATOR} MATCHES "Visual Studio.*") + set(ANTLR4_BUILD_COMMAND + ${CMAKE_COMMAND} + --build . + --config $(Configuration) + --target) +elseif(${CMAKE_GENERATOR} MATCHES "Xcode.*") + set(ANTLR4_BUILD_COMMAND + ${CMAKE_COMMAND} + --build . + --config $(CONFIGURATION) + --target) +else() + set(ANTLR4_BUILD_COMMAND + ${CMAKE_COMMAND} + --build . + --target) +endif() - # Find all the input files - FILE(GLOB generated_files ${ANTLR4CPP_GENERATED_SRC_DIR}/${antlr4cpp_project_namespace}/*.cpp) +if(NOT DEFINED ANTLR4_WITH_STATIC_CRT) + set(ANTLR4_WITH_STATIC_CRT ON) +endif() - # 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}") +if(ANTLR4_ZIP_REPOSITORY) + ExternalProject_Add( + antlr4_runtime + PREFIX antlr4_runtime + URL ${ANTLR4_ZIP_REPOSITORY} + DOWNLOAD_DIR ${CMAKE_CURRENT_BINARY_DIR} + BUILD_COMMAND "" + BUILD_IN_SOURCE 1 + SOURCE_DIR ${ANTLR4_ROOT} + SOURCE_SUBDIR runtime/Cpp + CMAKE_CACHE_ARGS + -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} + -DWITH_STATIC_CRT:BOOL=${ANTLR4_WITH_STATIC_CRT} + INSTALL_COMMAND "" + EXCLUDE_FROM_ALL 1) +else() + ExternalProject_Add( + antlr4_runtime + PREFIX antlr4_runtime + GIT_REPOSITORY ${ANTLR4_GIT_REPOSITORY} + GIT_TAG ${ANTLR4_TAG} + DOWNLOAD_DIR ${CMAKE_CURRENT_BINARY_DIR} + BUILD_COMMAND "" + BUILD_IN_SOURCE 1 + SOURCE_DIR ${ANTLR4_ROOT} + SOURCE_SUBDIR runtime/Cpp + CMAKE_CACHE_ARGS + -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} + -DWITH_STATIC_CRT:BOOL=${ANTLR4_WITH_STATIC_CRT} + INSTALL_COMMAND "" + EXCLUDE_FROM_ALL 1) +endif() - # 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}") +# Seperate build step as rarely people want both +ExternalProject_Add_Step( + antlr4_runtime + build_static + COMMAND ${ANTLR4_BUILD_COMMAND} antlr4_static + # Depend on target instead of step (a custom command) + # to avoid running dependent steps concurrently + DEPENDS antlr4_runtime + BYPRODUCTS ${ANTLR4_STATIC_LIBRARIES} + EXCLUDE_FROM_MAIN 1 + WORKING_DIRECTORY ${ANTLR4_ROOT}) +ExternalProject_Add_StepTargets(antlr4_runtime build_static) -endmacro() +add_library(antlr4_static STATIC IMPORTED) +add_dependencies(antlr4_static antlr4_runtime-build_static) +set_target_properties(antlr4_static PROPERTIES + IMPORTED_LOCATION ${ANTLR4_STATIC_LIBRARIES}) + +ExternalProject_Add_Step( + antlr4_runtime + build_shared + COMMAND ${ANTLR4_BUILD_COMMAND} antlr4_shared + # Depend on target instead of step (a custom command) + # to avoid running dependent steps concurrently + DEPENDS antlr4_runtime + BYPRODUCTS ${ANTLR4_SHARED_LIBRARIES} ${ANTLR4_RUNTIME_LIBRARIES} + EXCLUDE_FROM_MAIN 1 + WORKING_DIRECTORY ${ANTLR4_ROOT}) +ExternalProject_Add_StepTargets(antlr4_runtime build_shared) + +add_library(antlr4_shared SHARED IMPORTED) +add_dependencies(antlr4_shared antlr4_runtime-build_shared) +set_target_properties(antlr4_shared PROPERTIES + IMPORTED_LOCATION ${ANTLR4_RUNTIME_LIBRARIES}) +if(ANTLR4_SHARED_LIBRARIES) + set_target_properties(antlr4_shared PROPERTIES + IMPORTED_IMPLIB ${ANTLR4_SHARED_LIBRARIES}) +endif() diff --git a/runtime/Cpp/cmake/FindANTLR.cmake b/runtime/Cpp/cmake/FindANTLR.cmake new file mode 100644 index 000000000..bb6c7b28f --- /dev/null +++ b/runtime/Cpp/cmake/FindANTLR.cmake @@ -0,0 +1,124 @@ +find_package(Java QUIET COMPONENTS Runtime) + +if(NOT ANTLR_EXECUTABLE) + find_program(ANTLR_EXECUTABLE + NAMES antlr.jar antlr4.jar antlr-4.jar antlr-4.7.1-complete.jar) +endif() + +if(ANTLR_EXECUTABLE AND Java_JAVA_EXECUTABLE) + execute_process( + COMMAND ${Java_JAVA_EXECUTABLE} -jar ${ANTLR_EXECUTABLE} + OUTPUT_VARIABLE ANTLR_COMMAND_OUTPUT + ERROR_VARIABLE ANTLR_COMMAND_ERROR + RESULT_VARIABLE ANTLR_COMMAND_RESULT + OUTPUT_STRIP_TRAILING_WHITESPACE) + + if(ANTLR_COMMAND_RESULT EQUAL 0) + string(REGEX MATCH "Version [0-9]+(\\.[0-9])*" ANTLR_VERSION ${ANTLR_COMMAND_OUTPUT}) + string(REPLACE "Version " "" ANTLR_VERSION ${ANTLR_VERSION}) + else() + message( + SEND_ERROR + "Command '${Java_JAVA_EXECUTABLE} -jar ${ANTLR_EXECUTABLE}' " + "failed with the output '${ANTLR_COMMAND_ERROR}'") + endif() + + macro(ANTLR_TARGET Name InputFile) + set(ANTLR_OPTIONS LEXER PARSER LISTENER VISITOR) + set(ANTLR_ONE_VALUE_ARGS PACKAGE OUTPUT_DIRECTORY DEPENDS_ANTLR) + set(ANTLR_MULTI_VALUE_ARGS COMPILE_FLAGS DEPENDS) + cmake_parse_arguments(ANTLR_TARGET + "${ANTLR_OPTIONS}" + "${ANTLR_ONE_VALUE_ARGS}" + "${ANTLR_MULTI_VALUE_ARGS}" + ${ARGN}) + + set(ANTLR_${Name}_INPUT ${InputFile}) + + get_filename_component(ANTLR_INPUT ${InputFile} NAME_WE) + + if(ANTLR_TARGET_OUTPUT_DIRECTORY) + set(ANTLR_${Name}_OUTPUT_DIR ${ANTLR_TARGET_OUTPUT_DIRECTORY}) + else() + set(ANTLR_${Name}_OUTPUT_DIR + ${CMAKE_CURRENT_BINARY_DIR}/antlr4cpp_generated_src/${ANTLR_INPUT}) + endif() + + unset(ANTLR_${Name}_CXX_OUTPUTS) + + if((ANTLR_TARGET_LEXER AND NOT ANTLR_TARGET_PARSER) OR + (ANTLR_TARGET_PARSER AND NOT ANTLR_TARGET_LEXER)) + list(APPEND ANTLR_${Name}_CXX_OUTPUTS + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}.h + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}.cpp) + set(ANTLR_${Name}_OUTPUTS + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}.interp + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}.tokens) + else() + list(APPEND ANTLR_${Name}_CXX_OUTPUTS + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Lexer.h + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Lexer.cpp + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Parser.h + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Parser.cpp) + list(APPEND ANTLR_${Name}_OUTPUTS + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Lexer.interp + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Lexer.tokens) + endif() + + if(ANTLR_TARGET_LISTENER) + list(APPEND ANTLR_${Name}_CXX_OUTPUTS + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}BaseListener.h + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}BaseListener.cpp + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Listener.h + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Listener.cpp) + list(APPEND ANTLR_TARGET_COMPILE_FLAGS -listener) + endif() + + if(ANTLR_TARGET_VISITOR) + list(APPEND ANTLR_${Name}_CXX_OUTPUTS + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}BaseVisitor.h + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}BaseVisitor.cpp + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Visitor.h + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Visitor.cpp) + list(APPEND ANTLR_TARGET_COMPILE_FLAGS -visitor) + endif() + + if(ANTLR_TARGET_PACKAGE) + list(APPEND ANTLR_TARGET_COMPILE_FLAGS -package ${ANTLR_TARGET_PACKAGE}) + endif() + + list(APPEND ANTLR_${Name}_OUTPUTS ${ANTLR_${Name}_CXX_OUTPUTS}) + + if(ANTLR_TARGET_DEPENDS_ANTLR) + if(ANTLR_${ANTLR_TARGET_DEPENDS_ANTLR}_INPUT) + list(APPEND ANTLR_TARGET_DEPENDS + ${ANTLR_${ANTLR_TARGET_DEPENDS_ANTLR}_INPUT}) + list(APPEND ANTLR_TARGET_DEPENDS + ${ANTLR_${ANTLR_TARGET_DEPENDS_ANTLR}_OUTPUTS}) + else() + message(SEND_ERROR + "ANTLR target '${ANTLR_TARGET_DEPENDS_ANTLR}' not found") + endif() + endif() + + add_custom_command( + OUTPUT ${ANTLR_${Name}_OUTPUTS} + COMMAND ${Java_JAVA_EXECUTABLE} -jar ${ANTLR_EXECUTABLE} + ${InputFile} + -o ${ANTLR_${Name}_OUTPUT_DIR} + -no-listener + -Dlanguage=Cpp + ${ANTLR_TARGET_COMPILE_FLAGS} + DEPENDS ${InputFile} + ${ANTLR_TARGET_DEPENDS} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMENT "Building ${Name} with ANTLR ${ANTLR_VERSION}") + endmacro(ANTLR_TARGET) + +endif(ANTLR_EXECUTABLE AND Java_JAVA_EXECUTABLE) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + ANTLR + REQUIRED_VARS ANTLR_EXECUTABLE Java_JAVA_EXECUTABLE + VERSION_VAR ANTLR_VERSION) diff --git a/runtime/Cpp/cmake/README.md b/runtime/Cpp/cmake/README.md new file mode 100644 index 000000000..7d74b66a8 --- /dev/null +++ b/runtime/Cpp/cmake/README.md @@ -0,0 +1,154 @@ +## Getting started with Antlr4Cpp + +Here is how you can use this external project to create the antlr4cpp demo to start your project off. + +1. Create your project source folder somewhere. e.g. ~/srcfolder/ + 1. Make a subfolder cmake + 2. Copy the files in this folder to srcfolder/cmake + 3. Cut below and use it to create srcfolder/CMakeLists.txt + 4. Copy main.cpp, TLexer.g4 and TParser.g4 to ./srcfolder/ from [here](https://github.com/antlr/antlr4/tree/master/runtime/Cpp/demo) +2. Make a build folder e.g. ~/buildfolder/ +3. From the buildfolder, run `cmake ~/srcfolder; make` + +```cmake +# minimum required CMAKE version +CMAKE_MINIMUM_REQUIRED(VERSION 3.7 FATAL_ERROR) + +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) + +# compiler must be 11 or 14 +set(CMAKE_CXX_STANDARD 11) + +# required if linking to static library +add_definitions(-DANTLR4CPP_STATIC) + +# using /MD flag for antlr4_runtime (for Visual C++ compilers only) +set(ANTLR4_WITH_STATIC_CRT OFF) +# add external build for antlrcpp +include(ExternalAntlr4Cpp) +# add antrl4cpp artifacts to project environment +include_directories(${ANTLR4_INCLUDE_DIRS}) + +# set variable pointing to the antlr tool that supports C++ +# this is not required if the jar file can be found under PATH environment +set(ANTLR_EXECUTABLE /home/user/antlr-4.7.1-complete.jar) +# add macros to generate ANTLR Cpp code from grammar +find_package(ANTLR REQUIRED) + +# Call macro to add lexer and grammar to your build dependencies. +antlr_target(SampleGrammarLexer TLexer.g4 LEXER + PACKAGE antlrcpptest) +antlr_target(SampleGrammarParser TParser.g4 PARSER + PACKAGE antlrcpptest + DEPENDS_ANTLR SampleGrammarLexer) + +# include generated files in project environment +include_directories(${ANTLR_SampleGrammarLexer_OUTPUT_DIR}) +include_directories(${ANTLR_SampleGrammarParser_OUTPUT_DIR}) + +# add generated grammar to demo binary target +add_executable(demo main.cpp + ${ANTLR_SampleGrammarLexer_CXX_OUTPUTS} + ${ANTLR_SampleGrammarParser_CXX_OUTPUTS}) +target_link_libraries(demo antlr4_static) +``` + +## Documentation for FindANTLR + +The module defines the following variables: + +``` +ANTLR_FOUND - true is ANTLR jar executable is found +ANTLR_EXECUTABLE - the path to the ANTLR jar executable +ANTLR_VERSION - the version of ANTLR +``` + +If ANTLR is found, the module will provide the macros: + +``` +ANTLR_TARGET( + [PACKAGE namespace] + [OUTPUT_DIRECTORY dir] + [DEPENDS_ANTLR ] + [COMPILE_FLAGS [args...]] + [DEPENDS [depends...]] + [LEXER] + [PARSER] + [LISTENER] + [VISITOR]) +``` + +which creates a custom command to generate C++ files from ``. Running the macro defines the following variables: + +``` +ANTLR_${name}_INPUT - the ANTLR input used for the macro +ANTLR_${name}_OUTPUTS - the outputs generated by ANTLR +ANTLR_${name}_CXX_OUTPUTS - the C++ outputs generated by ANTLR +ANTLR_${name}_OUTPUT_DIR - the output directory for ANTLR +``` + +The options are: + +* `PACKAGE` - defines a namespace for the generated C++ files +* `OUTPUT_DIRECTORY` - the output directory for the generated files. By default it uses `${CMAKE_CURRENT_BINARY_DIR}` +* `DEPENDS_ANTLR` - the dependent target generated from antlr_target for the current call +* `COMPILE_FLAGS` - additional compile flags for ANTLR tool +* `DEPENDS` - specify the files on which the command depends. It works the same way `DEPENDS` in [`add_custom_command()`](https://cmake.org/cmake/help/v3.11/command/add_custom_command.html) +* `LEXER` - specify that the input file is a lexer grammar +* `PARSER` - specify that the input file is a parser grammar +* `LISTENER` - tell ANTLR tool to generate a parse tree listener +* `VISITOR` - tell ANTLR tool to generate a parse tree visitor + +### Examples + +To generate C++ files from an ANTLR input file T.g4, which defines both lexer and parser grammar one may call: + +```cmake +find_package(ANTLR REQUIRED) +antlr_target(Sample T.g4) +``` + +Note that this command will do nothing unless the outputs of `Sample`, i.e. `ANTLR_Sample_CXX_OUTPUTS` gets used by some target. + +## Documentation for ExternalAntlr4Cpp + +Including ExternalAntlr4Cpp will add `antlr4_static` and `antlr4_shared` as an optional target. It will also define the following variables: + +``` +ANTLR4_INCLUDE_DIRS - the include directory that should be included when compiling C++ source file +ANTLR4_STATIC_LIBRARIES - path to antlr4 static library +ANTLR4_SHARED_LIBRARIES - path to antlr4 shared library +ANTLR4_RUNTIME_LIBRARIES - path to antlr4 shared runtime library (such as DLL, DYLIB and SO file) +ANTLR4_TAG - branch/tag used for building antlr4 library +``` + +`ANTLR4_TAG` is set to master branch by default to keep antlr4 updated. However, it will be required to rebuild after every `clean` is called. Set `ANTLR4_TAG` to a desired commit hash value to avoid rebuilding after every `clean` and keep the build stable, at the cost of not automatically update to latest commit. + +The ANTLR C++ runtime source is downloaded from GitHub by default. However, users may specify `ANTLR4_ZIP_REPOSITORY` to list the zip file from [ANTLR downloads](http://www.antlr.org/download.html) (under *C++ Target*). This variable can list a zip file included in the project directory; this is useful for maintaining a canonical source for each new build. + +Visual C++ compiler users may want to additionally define `ANTLR4_WITH_STATIC_CRT` before including the file. Set `ANTLR4_WITH_STATIC_CRT` to true if ANTLR4 C++ runtime library should be compiled with `/MT` flag, otherwise will be compiled with `/MD` flag. This variable has a default value of `OFF`. Changing `ANTLR4_WITH_STATIC_CRT` after building the library may require reinitialization of CMake or `clean` for the library to get rebuilt. + +### Examples + +To build and link ANTLR4 static library to a target one may call: + +```cmake +include(ExternalAntlr4Cpp) +include_directories(${ANTLR4_INCLUDE_DIRS}) +add_executable(output main.cpp) +target_link_libraries(output antlr4_static) +``` + +It may also be a good idea to copy the runtime libraries (DLL, DYLIB or SO file) to the executable for it to run properly after build. i.e. To build and link antlr4 shared library to a target one may call: + +```cmake +include(ExternalAntlr4Cpp) +include_directories(${ANTLR4_INCLUDE_DIRS}) +add_executable(output main.cpp) +target_link_libraries(output antlr4_shared) +add_custom_command(TARGET output + POST_BUILD + COMMAND ${CMAKE_COMMAND} + -E copy ${ANTLR4_RUNTIME_LIBRARIES} . + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) +``` diff --git a/runtime/Cpp/demo/CMakeLists.txt b/runtime/Cpp/demo/CMakeLists.txt index bd2bcffe3..23b4c4060 100644 --- a/runtime/Cpp/demo/CMakeLists.txt +++ b/runtime/Cpp/demo/CMakeLists.txt @@ -12,13 +12,13 @@ set(antlr4-demo-GENERATED_SRC ${PROJECT_SOURCE_DIR}/demo/generated/TParserVisitor.cpp ) -foreach( src_file ${antlr4-demo-GENERATED_SRC} ) +foreach(src_file ${antlr4-demo-GENERATED_SRC}) set_source_files_properties( ${src_file} PROPERTIES GENERATED TRUE ) -endforeach( src_file ${antlr4-demo-GENERATED_SRC} ) +endforeach(src_file ${antlr4-demo-GENERATED_SRC}) add_custom_target(GenerateParser DEPENDS ${antlr4-demo-GENERATED_SRC}) add_custom_command(OUTPUT ${antlr4-demo-GENERATED_SRC} @@ -46,26 +46,26 @@ set(antlr4-demo_SRC ${antlr4-demo-GENERATED_SRC} ) -if (NOT CMAKE_CXX_COMPILER_ID MATCHES "MSVC") +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} ) +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} ) +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") +if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") target_compile_options(antlr4-demo PRIVATE "/MT$<$:d>") endif() diff --git a/runtime/Cpp/demo/Mac/antlrcpp-demo.xcodeproj/project.pbxproj b/runtime/Cpp/demo/Mac/antlrcpp-demo.xcodeproj/project.pbxproj index 2279d8f66..77ad3f4f7 100644 --- a/runtime/Cpp/demo/Mac/antlrcpp-demo.xcodeproj/project.pbxproj +++ b/runtime/Cpp/demo/Mac/antlrcpp-demo.xcodeproj/project.pbxproj @@ -250,8 +250,8 @@ 37D727A21867AF1E007B6D10 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0800; - ORGANIZATIONNAME = "Dan McLaughlin"; + LastUpgradeCheck = 1010; + ORGANIZATIONNAME = "ANTLR4 Project"; TargetAttributes = { 27C66A661C9591280021E494 = { CreatedOnToolsVersion = 7.2.1; @@ -415,14 +415,22 @@ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -469,14 +477,22 @@ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; diff --git a/runtime/Cpp/demo/Mac/antlrcpp-demo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/runtime/Cpp/demo/Mac/antlrcpp-demo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/runtime/Cpp/demo/Mac/antlrcpp-demo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/runtime/Cpp/demo/Mac/antlrcpp-demo.xcodeproj/xcshareddata/xcschemes/antlr4-cpp-demo.xcscheme b/runtime/Cpp/demo/Mac/antlrcpp-demo.xcodeproj/xcshareddata/xcschemes/antlr4-cpp-demo.xcscheme index d603caf47..8e3cfa5d8 100644 --- a/runtime/Cpp/demo/Mac/antlrcpp-demo.xcodeproj/xcshareddata/xcschemes/antlr4-cpp-demo.xcscheme +++ b/runtime/Cpp/demo/Mac/antlrcpp-demo.xcodeproj/xcshareddata/xcschemes/antlr4-cpp-demo.xcscheme @@ -1,6 +1,6 @@ + codeCoverageEnabled = "YES" + shouldUseLaunchSchemeArgsEnv = "YES"> diff --git a/runtime/Cpp/demo/Mac/antlrcpp-demo.xcodeproj/xcshareddata/xcschemes/antlrcpp Tests.xcscheme b/runtime/Cpp/demo/Mac/antlrcpp-demo.xcodeproj/xcshareddata/xcschemes/antlrcpp Tests.xcscheme index dcca4cb68..8edff6632 100644 --- a/runtime/Cpp/demo/Mac/antlrcpp-demo.xcodeproj/xcshareddata/xcschemes/antlrcpp Tests.xcscheme +++ b/runtime/Cpp/demo/Mac/antlrcpp-demo.xcodeproj/xcshareddata/xcschemes/antlrcpp Tests.xcscheme @@ -1,6 +1,6 @@ :d>") - target_compile_options(antlr4_static PRIVATE "/MT$<$:d>") +if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") + if(WITH_STATIC_CRT) + target_compile_options(antlr4_shared PRIVATE "/MT$<$:d>") + target_compile_options(antlr4_static PRIVATE "/MT$<$:d>") + else() + target_compile_options(antlr4_shared PRIVATE "/MD$<$:d>") + target_compile_options(antlr4_static PRIVATE "/MD$<$:d>") + endif() endif() set(static_lib_suffix "") -if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC") +if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") set(static_lib_suffix "-static") endif() -if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC") +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() diff --git a/runtime/Cpp/runtime/antlr4cpp-vs2013.vcxproj b/runtime/Cpp/runtime/antlr4cpp-vs2013.vcxproj index 80f9ebf77..47377c18a 100644 --- a/runtime/Cpp/runtime/antlr4cpp-vs2013.vcxproj +++ b/runtime/Cpp/runtime/antlr4cpp-vs2013.vcxproj @@ -35,7 +35,7 @@ - {A9762991-1B57-4DCE-90C0-EE42B96947BE} + {229A61DC-1207-4E4E-88B0-F4CB7205672D} Win32Proj antlr4cpp @@ -223,7 +223,7 @@ Level4 Disabled - ANTLR4CPP_EXPORTS;%(PreprocessorDefinitions) + ANTLR4CPP_STATIC;%(PreprocessorDefinitions) src/tree;src;%(AdditionalIncludeDirectories) @@ -305,7 +305,7 @@ MaxSpeed true true - ANTLR4CPP_EXPORTS;%(PreprocessorDefinitions) + ANTLR4CPP_STATIC;%(PreprocessorDefinitions) src/tree;src;%(AdditionalIncludeDirectories) diff --git a/runtime/Cpp/runtime/antlr4cpp-vs2015.vcxproj b/runtime/Cpp/runtime/antlr4cpp-vs2015.vcxproj index 909d0c572..9085761e8 100644 --- a/runtime/Cpp/runtime/antlr4cpp-vs2015.vcxproj +++ b/runtime/Cpp/runtime/antlr4cpp-vs2015.vcxproj @@ -230,7 +230,7 @@ Level4 Disabled - ANTLR4CPP_EXPORTS;%(PreprocessorDefinitions) + ANTLR4CPP_STATIC;%(PreprocessorDefinitions) src;%(AdditionalIncludeDirectories) @@ -317,7 +317,7 @@ MaxSpeed true true - ANTLR4CPP_EXPORTS;%(PreprocessorDefinitions) + ANTLR4CPP_STATIC;%(PreprocessorDefinitions) src;%(AdditionalIncludeDirectories) diff --git a/runtime/Cpp/runtime/antlr4cpp-vs2017.vcxproj b/runtime/Cpp/runtime/antlr4cpp-vs2017.vcxproj new file mode 100644 index 000000000..630ee34e9 --- /dev/null +++ b/runtime/Cpp/runtime/antlr4cpp-vs2017.vcxproj @@ -0,0 +1,652 @@ + + + + + Debug Static + Win32 + + + Debug Static + x64 + + + Debug DLL + Win32 + + + Debug DLL + x64 + + + Release Static + Win32 + + + Release Static + x64 + + + Release DLL + Win32 + + + Release DLL + x64 + + + + {83BE66CD-9C4F-4F84-B72A-DD1855C8FC8A} + Win32Proj + antlr4cpp + 10.0.16299.0 + + + + DynamicLibrary + true + Unicode + v141 + + + StaticLibrary + true + Unicode + v141 + + + DynamicLibrary + true + Unicode + v141 + + + StaticLibrary + true + Unicode + v141 + + + DynamicLibrary + false + true + Unicode + v141 + + + StaticLibrary + false + true + Unicode + v141 + + + DynamicLibrary + false + true + Unicode + v141 + + + StaticLibrary + false + true + Unicode + v141 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)bin\vs-2015\$(PlatformTarget)\$(Configuration)\ + $(SolutionDir)obj\$(PlatformTarget)\$(Configuration)\$(ProjectName)\ + antlr4-runtime + + + true + $(SolutionDir)bin\vs-2015\$(PlatformTarget)\$(Configuration)\ + $(SolutionDir)obj\$(PlatformTarget)\$(Configuration)\$(ProjectName)\ + antlr4-runtime + + + true + $(SolutionDir)bin\vs-2015\$(PlatformTarget)\$(Configuration)\ + $(SolutionDir)obj\$(PlatformTarget)\$(Configuration)\$(ProjectName)\ + antlr4-runtime + + + true + $(SolutionDir)bin\vs-2015\$(PlatformTarget)\$(Configuration)\ + $(SolutionDir)obj\$(PlatformTarget)\$(Configuration)\$(ProjectName)\ + antlr4-runtime + + + false + $(SolutionDir)bin\vs-2015\$(PlatformTarget)\$(Configuration)\ + $(SolutionDir)obj\$(PlatformTarget)\$(Configuration)\$(ProjectName)\ + antlr4-runtime + + + false + $(SolutionDir)bin\vs-2015\$(PlatformTarget)\$(Configuration)\ + $(SolutionDir)obj\$(PlatformTarget)\$(Configuration)\$(ProjectName)\ + antlr4-runtime + + + false + $(SolutionDir)bin\vs-2015\$(PlatformTarget)\$(Configuration)\ + $(SolutionDir)obj\$(PlatformTarget)\$(Configuration)\$(ProjectName)\ + antlr4-runtime + + + false + $(SolutionDir)bin\vs-2015\$(PlatformTarget)\$(Configuration)\ + $(SolutionDir)obj\$(PlatformTarget)\$(Configuration)\$(ProjectName)\ + antlr4-runtime + + + + Level4 + Disabled + ANTLR4CPP_EXPORTS;%(PreprocessorDefinitions) + src;%(AdditionalIncludeDirectories) + + + + + 4251 + true + false + + + Windows + true + + + + + Level4 + Disabled + ANTLR4CPP_EXPORTS;%(PreprocessorDefinitions) + src;%(AdditionalIncludeDirectories) + + + + + 4251 + true + false + + + Windows + true + + + + + Level4 + Disabled + ANTLR4CPP_EXPORTS;%(PreprocessorDefinitions) + src;%(AdditionalIncludeDirectories) + + + + + 4251 + true + false + + + Windows + true + + + + + Level4 + Disabled + ANTLR4CPP_STATIC;%(PreprocessorDefinitions) + src;%(AdditionalIncludeDirectories) + + + + + 4251 + true + false + + + Windows + true + + + + + Level4 + MaxSpeed + true + true + ANTLR4CPP_DLL;ANTLR4CPP_EXPORTS;%(PreprocessorDefinitions) + src;%(AdditionalIncludeDirectories) + + + + + 4251 + true + + + Windows + true + true + true + + + + + Level4 + MaxSpeed + true + true + ANTLR4CPP_EXPORTS;%(PreprocessorDefinitions) + src;%(AdditionalIncludeDirectories) + + + + + 4251 + true + + + Windows + true + true + true + + + + + Level4 + MaxSpeed + true + true + ANTLR4CPP_DLL;ANTLR4CPP_EXPORTS;%(PreprocessorDefinitions) + src;%(AdditionalIncludeDirectories) + + + + + 4251 + true + + + Windows + true + true + true + + + + + Level4 + MaxSpeed + true + true + ANTLR4CPP_STATIC;%(PreprocessorDefinitions) + src;%(AdditionalIncludeDirectories) + + + + + 4251 + true + + + Windows + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/runtime/Cpp/runtime/antlr4cpp-vs2017.vcxproj.filters b/runtime/Cpp/runtime/antlr4cpp-vs2017.vcxproj.filters new file mode 100644 index 000000000..cc1986923 --- /dev/null +++ b/runtime/Cpp/runtime/antlr4cpp-vs2017.vcxproj.filters @@ -0,0 +1,990 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {587a2726-4856-4d21-937a-fbaebaa90232} + + + {2662156f-1508-4dad-b991-a8298a6db9bf} + + + {5b1e59b1-7fa5-46a5-8d92-965bd709cca0} + + + {9de9fe74-5d67-441d-a972-3cebe6dfbfcc} + + + {89fd3896-0ab1-476d-8d64-a57f10a5e73b} + + + {23939d7b-8e11-421e-80eb-b2cfdfdd64e9} + + + {05f2bacb-b5b2-4ca3-abe1-ca9a7239ecaa} + + + {d3b2ae2d-836b-4c73-8180-aca4ebb7d658} + + + {6674a0f0-c65d-4a00-a9e5-1f243b89d0a2} + + + {1893fffe-7a2b-4708-8ce5-003aa9b749f7} + + + {053a0632-27bc-4043-b5e8-760951b3b5b9} + + + {048c180d-44cf-49ca-a7aa-d0053fea07f5} + + + {3181cae5-cc15-4050-8c45-22af44a823de} + + + {290632d2-c56e-4005-a417-eb83b9531e1a} + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\dfa + + + Header Files\dfa + + + Header Files\dfa + + + Header Files\dfa + + + Header Files\misc + + + Header Files\misc + + + Header Files\misc + + + Header Files\misc + + + Header Files\support + + + Header Files\support + + + Header Files\support + + + Header Files\support + + + Header Files\support + + + Header Files\tree + + + Header Files\tree + + + Header Files\tree + + + Header Files\tree + + + Header Files\tree + + + Header Files\tree + + + Header Files\tree + + + Header Files\tree + + + Header Files\tree + + + Header Files\tree + + + Header Files\tree + + + Header Files\tree + + + Header Files\tree + + + Header Files\tree\pattern + + + Header Files\tree\pattern + + + Header Files\tree\pattern + + + Header Files\tree\pattern + + + Header Files\tree\pattern + + + Header Files\tree\pattern + + + Header Files\tree\pattern + + + Header Files\tree\pattern + + + Header Files\tree\xpath + + + Header Files + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\atn + + + Header Files\misc + + + Header Files + + + Header Files + + + Header Files\support + + + Header Files\tree\xpath + + + Header Files\tree\xpath + + + Header Files\tree\xpath + + + Header Files\tree\xpath + + + Header Files\tree\xpath + + + Header Files\tree\xpath + + + Header Files\tree\xpath + + + Header Files\tree\xpath + + + Header Files\tree\xpath + + + Header Files + + + Header Files + + + Source Files\support + + + Header Files\tree + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\dfa + + + Source Files\dfa + + + Source Files\dfa + + + Source Files\dfa + + + Source Files\misc + + + Source Files\misc + + + Source Files\misc + + + Source Files\support + + + Source Files\support + + + Source Files\support + + + Source Files\tree + + + Source Files\tree + + + Source Files\tree + + + Source Files\tree + + + Source Files\tree\pattern + + + Source Files\tree\pattern + + + Source Files\tree\pattern + + + Source Files\tree\pattern + + + Source Files\tree\pattern + + + Source Files\tree\pattern + + + Source Files\tree\pattern + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files\atn + + + Source Files + + + Source Files + + + Source Files\support + + + Source Files\tree\xpath + + + Source Files\tree\xpath + + + Source Files\tree\xpath + + + Source Files\tree\xpath + + + Source Files\tree\xpath + + + Source Files\tree\xpath + + + Source Files\tree\xpath + + + Source Files\tree\xpath + + + Source Files\tree\xpath + + + Source Files\tree\xpath + + + Source Files + + + Source Files\tree + + + Source Files\tree + + + Source Files + + + Source Files + + + Source Files + + + Source Files\atn + + + Source Files\atn + + + Source Files\misc + + + Source Files + + + Source Files + + + Source Files + + + Source Files\support + + + Source Files\tree + + + Source Files\tree + + + Source Files\tree + + + Source Files\tree + + + Source Files\tree\pattern + + + \ No newline at end of file diff --git a/runtime/Cpp/runtime/antlrcpp.xcodeproj/project.pbxproj b/runtime/Cpp/runtime/antlrcpp.xcodeproj/project.pbxproj index bc7a3b238..d6822dfdd 100644 --- a/runtime/Cpp/runtime/antlrcpp.xcodeproj/project.pbxproj +++ b/runtime/Cpp/runtime/antlrcpp.xcodeproj/project.pbxproj @@ -1191,8 +1191,6 @@ 27745EFB1CE49C000067C6A3 /* RuntimeMetaData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RuntimeMetaData.cpp; sourceTree = ""; wrapsLines = 0; }; 27745EFC1CE49C000067C6A3 /* RuntimeMetaData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RuntimeMetaData.h; sourceTree = ""; }; 27874F1D1CCB7A0700AF1C53 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; - 278E313E1D9D6534001C28F9 /* Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Tests.m; sourceTree = ""; }; - 278E31401D9D6534001C28F9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 2793DC841F08083F00A84290 /* TokenSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TokenSource.cpp; sourceTree = ""; }; 2793DC881F08087500A84290 /* Chunk.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Chunk.cpp; sourceTree = ""; }; 2793DC8C1F08088F00A84290 /* ParseTreeListener.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParseTreeListener.cpp; sourceTree = ""; }; @@ -1626,15 +1624,6 @@ name = "Linked Frameworks"; sourceTree = ""; }; - 278E313D1D9D6534001C28F9 /* Tests */ = { - isa = PBXGroup; - children = ( - 278E313E1D9D6534001C28F9 /* Tests.m */, - 278E31401D9D6534001C28F9 /* Info.plist */, - ); - path = Tests; - sourceTree = ""; - }; 27DB448A1D045537007E790B /* xpath */ = { isa = PBXGroup; children = ( @@ -1667,7 +1656,6 @@ children = ( 270C67F11CDB4F1E00116E17 /* antlrcpp-ios */, 27874F221CCBB34200AF1C53 /* Linked Frameworks */, - 278E313D1D9D6534001C28F9 /* Tests */, 37D727AB1867AF1E007B6D10 /* Products */, 276E5C0A1CDB57AA003FF4B4 /* runtime */, ); @@ -2238,7 +2226,7 @@ 37D727A21867AF1E007B6D10 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0800; + LastUpgradeCheck = 1010; ORGANIZATIONNAME = ANTLR; TargetAttributes = { 270C67EF1CDB4F1E00116E17 = { @@ -2855,14 +2843,20 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_ASSIGN_ENUM = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; @@ -2908,14 +2902,20 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_ASSIGN_ENUM = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; diff --git a/runtime/Cpp/runtime/antlrcpp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/runtime/Cpp/runtime/antlrcpp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/runtime/Cpp/runtime/antlrcpp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/runtime/Cpp/runtime/antlrcpp.xcodeproj/xcshareddata/xcschemes/antlr4.xcscheme b/runtime/Cpp/runtime/antlrcpp.xcodeproj/xcshareddata/xcschemes/antlr4.xcscheme index c31017b1c..740698b37 100644 --- a/runtime/Cpp/runtime/antlrcpp.xcodeproj/xcshareddata/xcschemes/antlr4.xcscheme +++ b/runtime/Cpp/runtime/antlrcpp.xcodeproj/xcshareddata/xcschemes/antlr4.xcscheme @@ -1,6 +1,6 @@ get the current context. virtual void enterRule(ParserRuleContext *localctx, size_t state, size_t ruleIndex); - virtual void exitRule(); + void exitRule(); virtual void enterOuterAlt(ParserRuleContext *localctx, size_t altNum); diff --git a/runtime/Cpp/runtime/src/antlr4-common.h b/runtime/Cpp/runtime/src/antlr4-common.h index ec1ccc758..25d890b3f 100644 --- a/runtime/Cpp/runtime/src/antlr4-common.h +++ b/runtime/Cpp/runtime/src/antlr4-common.h @@ -78,7 +78,12 @@ #endif #endif - class ANTLR4CPP_PUBLIC std::exception; // Needed for VS 2015. + #if defined(_MSC_VER) && !defined(__clang__) + // clang-cl should escape this to prevent [ignored-attributes]. + namespace std { + class ANTLR4CPP_PUBLIC exception; // Prevents warning C4275 from MSVC. + } // namespace std + #endif #elif defined(__APPLE__) typedef std::u32string UTF32String; diff --git a/runtime/Cpp/runtime/src/atn/ATNState.cpp b/runtime/Cpp/runtime/src/atn/ATNState.cpp index fe8138098..9bc074ce0 100755 --- a/runtime/Cpp/runtime/src/atn/ATNState.cpp +++ b/runtime/Cpp/runtime/src/atn/ATNState.cpp @@ -66,6 +66,7 @@ void ATNState::addTransition(size_t index, Transition *e) { } Transition *ATNState::removeTransition(size_t index) { + Transition *result = transitions[index]; transitions.erase(transitions.begin() + index); - return nullptr; + return result; } diff --git a/runtime/Cpp/runtime/src/atn/LexerATNSimulator.cpp b/runtime/Cpp/runtime/src/atn/LexerATNSimulator.cpp index 25ac26028..c21ef0b2c 100755 --- a/runtime/Cpp/runtime/src/atn/LexerATNSimulator.cpp +++ b/runtime/Cpp/runtime/src/atn/LexerATNSimulator.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +/* 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. */ @@ -99,7 +99,7 @@ void LexerATNSimulator::clearDFA() { size_t size = _decisionToDFA.size(); _decisionToDFA.clear(); for (size_t d = 0; d < size; ++d) { - _decisionToDFA.push_back(dfa::DFA(atn.getDecisionState(d), d)); + _decisionToDFA.emplace_back(atn.getDecisionState(d), d); } } @@ -192,7 +192,7 @@ dfa::DFAState *LexerATNSimulator::getExistingTargetState(dfa::DFAState *s, size_ #endif if (iterator != s->edges.end()) - retval = iterator->second; + retval = iterator->second; } _edgeLock.readUnlock(); return retval; diff --git a/runtime/Cpp/runtime/src/atn/ParserATNSimulator.cpp b/runtime/Cpp/runtime/src/atn/ParserATNSimulator.cpp index aaa9e820c..1613d0bda 100755 --- a/runtime/Cpp/runtime/src/atn/ParserATNSimulator.cpp +++ b/runtime/Cpp/runtime/src/atn/ParserATNSimulator.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +/* 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. */ @@ -127,8 +127,10 @@ size_t ParserATNSimulator::adaptivePredict(TokenStream *input, size_t decision, dfa::DFAState *newState = new dfa::DFAState(std::move(s0_closure)); /* mem-check: managed by the DFA or deleted below */ s0 = addDFAState(dfa, newState); - delete dfa.s0; // Delete existing s0 DFA state, if there's any. - dfa.s0 = s0; + if (dfa.s0 != s0) { + delete dfa.s0; // Delete existing s0 DFA state, if there's any. + dfa.s0 = s0; + } if (s0 != newState) { delete newState; // If there was already a state with this config set we don't need the new one. } @@ -891,15 +893,6 @@ void ParserATNSimulator::closure_(Ref const& config, ATNConfigSet *co bool continueCollecting = !is(t) && collectPredicates; Ref c = getEpsilonTarget(config, t, continueCollecting, depth == 0, fullCtx, treatEofAsEpsilon); if (c != nullptr) { - if (!t->isEpsilon()) { - // avoid infinite recursion for EOF* and EOF+ - if (closureBusy.count(c) == 0) { - closureBusy.insert(c); - } else { - continue; - } - } - int newDepth = depth; if (is(config->state)) { assert(!fullCtx); @@ -924,6 +917,16 @@ void ParserATNSimulator::closure_(Ref const& config, ATNConfigSet *co } c->reachesIntoOuterContext++; + + if (!t->isEpsilon()) { + // avoid infinite recursion for EOF* and EOF+ + if (closureBusy.count(c) == 0) { + closureBusy.insert(c); + } else { + continue; + } + } + configs->dipsIntoOuterContext = true; // TO_DO: can remove? only care when we add to set per middle of this method assert(newDepth > INT_MIN); @@ -932,7 +935,16 @@ void ParserATNSimulator::closure_(Ref const& config, ATNConfigSet *co std::cout << "dips into outer ctx: " << c << std::endl; #endif - } else if (is(t)) { + } else if (!t->isEpsilon()) { + // avoid infinite recursion for EOF* and EOF+ + if (closureBusy.count(c) == 0) { + closureBusy.insert(c); + } else { + continue; + } + } + + if (is(t)) { // latch when newDepth goes negative - once we step out of the entry context we can't return if (newDepth >= 0) { newDepth++; diff --git a/runtime/Cpp/runtime/src/atn/ProfilingATNSimulator.cpp b/runtime/Cpp/runtime/src/atn/ProfilingATNSimulator.cpp index 6cd1a1044..6b2762022 100755 --- a/runtime/Cpp/runtime/src/atn/ProfilingATNSimulator.cpp +++ b/runtime/Cpp/runtime/src/atn/ProfilingATNSimulator.cpp @@ -35,7 +35,7 @@ size_t ProfilingATNSimulator::adaptivePredict(TokenStream *input, size_t decisio _sllStopIndex = -1; _llStopIndex = -1; _currentDecision = decision; - high_resolution_clock::time_point start = high_resolution_clock::now(); // expensive but useful info + high_resolution_clock::time_point start = high_resolution_clock::now(); size_t alt = ParserATNSimulator::adaptivePredict(input, decision, outerContext); high_resolution_clock::time_point stop = high_resolution_clock::now(); _decisions[decision].timeInPrediction += duration_cast(stop - start).count(); diff --git a/runtime/Cpp/runtime/src/atn/TokensStartState.h b/runtime/Cpp/runtime/src/atn/TokensStartState.h index 7657ffb75..e534d04ee 100755 --- a/runtime/Cpp/runtime/src/atn/TokensStartState.h +++ b/runtime/Cpp/runtime/src/atn/TokensStartState.h @@ -14,7 +14,7 @@ namespace atn { class ANTLR4CPP_PUBLIC TokensStartState final : public DecisionState { public: - virtual size_t getStateType(); + virtual size_t getStateType() override; }; } // namespace atn diff --git a/runtime/Cpp/runtime/src/misc/IntervalSet.h b/runtime/Cpp/runtime/src/misc/IntervalSet.h index af09e3465..aa2adf66f 100755 --- a/runtime/Cpp/runtime/src/misc/IntervalSet.h +++ b/runtime/Cpp/runtime/src/misc/IntervalSet.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +/* 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. */ @@ -40,11 +40,10 @@ namespace misc { IntervalSet(IntervalSet&& set); template - IntervalSet(int, T1 t1, T_NEXT&&... next) : IntervalSet() - { - // The first int argument is an ignored count for compatibility - // with the previous varargs based interface. - addItems(t1, std::forward(next)...); + IntervalSet(int, T1 t1, T_NEXT&&... next) : IntervalSet() { + // The first int argument is an ignored count for compatibility + // with the previous varargs based interface. + addItems(t1, std::forward(next)...); } IntervalSet& operator=(IntervalSet const& set); @@ -78,10 +77,9 @@ namespace misc { IntervalSet& addAll(const IntervalSet &set); template - void addItems(T1 t1, T_NEXT&&... next) - { - add(t1); - addItems(std::forward(next)...); + void addItems(T1 t1, T_NEXT&&... next) { + add(t1); + addItems(std::forward(next)...); } IntervalSet complement(ssize_t minElement, ssize_t maxElement) const; diff --git a/runtime/Cpp/runtime/src/support/Any.cpp b/runtime/Cpp/runtime/src/support/Any.cpp index 3dd1a94bf..b324cc15d 100644 --- a/runtime/Cpp/runtime/src/support/Any.cpp +++ b/runtime/Cpp/runtime/src/support/Any.cpp @@ -11,6 +11,3 @@ Any::~Any() { delete _ptr; } - -Any::Base::~Base() { -} diff --git a/runtime/Cpp/runtime/src/support/Any.h b/runtime/Cpp/runtime/src/support/Any.h index 3d8845c70..817490a3a 100644 --- a/runtime/Cpp/runtime/src/support/Any.h +++ b/runtime/Cpp/runtime/src/support/Any.h @@ -100,7 +100,7 @@ struct ANTLR4CPP_PUBLIC Any private: struct Base { - virtual ~Base(); + virtual ~Base() {}; virtual Base* clone() const = 0; }; @@ -112,10 +112,21 @@ private: T value; + Base* clone() const { + return clone<>(); + } + + private: + template::value, int>::type = 0> Base* clone() const { return new Derived(value); } + template::value, int>::type = 0> + Base* clone() const { + return nullptr; + } + }; Base* clone() const diff --git a/runtime/Cpp/runtime/src/tree/pattern/TagChunk.h b/runtime/Cpp/runtime/src/tree/pattern/TagChunk.h index a39e34f23..3d0c9f8d8 100755 --- a/runtime/Cpp/runtime/src/tree/pattern/TagChunk.h +++ b/runtime/Cpp/runtime/src/tree/pattern/TagChunk.h @@ -70,7 +70,7 @@ namespace pattern { /// are returned in the form {@code label:tag}, and unlabeled tags are /// returned as just the tag name. /// - virtual std::string toString(); + virtual std::string toString() override; private: /// This is the backing field for . diff --git a/runtime/Cpp/runtime/src/tree/pattern/TextChunk.h b/runtime/Cpp/runtime/src/tree/pattern/TextChunk.h index 3b828a84d..1cbc0ddb2 100755 --- a/runtime/Cpp/runtime/src/tree/pattern/TextChunk.h +++ b/runtime/Cpp/runtime/src/tree/pattern/TextChunk.h @@ -43,7 +43,7 @@ namespace pattern { /// The implementation for returns the result of /// in single quotes. /// - virtual std::string toString(); + virtual std::string toString() override; }; } // namespace pattern diff --git a/runtime/Java/pom.xml b/runtime/Java/pom.xml index d7a393f76..c8163725d 100644 --- a/runtime/Java/pom.xml +++ b/runtime/Java/pom.xml @@ -96,6 +96,7 @@ process-classes + org.antlr.antlr4.runtime org.antlr.antlr4-runtime diff --git a/runtime/JavaScript/src/antlr4/InputStream.js b/runtime/JavaScript/src/antlr4/InputStream.js index bb53a5cc2..77db1533d 100644 --- a/runtime/JavaScript/src/antlr4/InputStream.js +++ b/runtime/JavaScript/src/antlr4/InputStream.js @@ -11,7 +11,7 @@ require('./polyfills/fromcodepoint'); // Vacuum all input from a string and then treat it like a buffer. -function _loadString(stream, decodeToUnicodeCodePoints) { +function _loadString(stream) { stream._index = 0; stream.data = []; if (stream.decodeToUnicodeCodePoints) { diff --git a/runtime/JavaScript/src/antlr4/package.json b/runtime/JavaScript/src/antlr4/package.json index 9584e17ee..ac02fb1be 100644 --- a/runtime/JavaScript/src/antlr4/package.json +++ b/runtime/JavaScript/src/antlr4/package.json @@ -11,7 +11,7 @@ "antlr4", "grammar" ], - "license": "BSD", + "license": "BSD-3-Clause", "bugs": { "url": "https://github.com/antlr/antlr4/issues" }, diff --git a/runtime/JavaScript/src/antlr4/tree/Tree.js b/runtime/JavaScript/src/antlr4/tree/Tree.js index 468d7a8a7..515b122b5 100644 --- a/runtime/JavaScript/src/antlr4/tree/Tree.js +++ b/runtime/JavaScript/src/antlr4/tree/Tree.js @@ -73,7 +73,11 @@ ParseTreeVisitor.prototype.visit = function(ctx) { }; ParseTreeVisitor.prototype.visitChildren = function(ctx) { - return this.visit(ctx.children); + if (ctx.children) { + return this.visit(ctx.children); + } else { + return null; + } } ParseTreeVisitor.prototype.visitTerminal = function(node) { diff --git a/runtime/Python3/src/antlr4/StdinStream.py b/runtime/Python3/src/antlr4/StdinStream.py new file mode 100644 index 000000000..f044fc4d7 --- /dev/null +++ b/runtime/Python3/src/antlr4/StdinStream.py @@ -0,0 +1,11 @@ +import codecs +import sys + +from antlr4.InputStream import InputStream + + +class StdinStream(InputStream): + def __init__(self, encoding:str='ascii', errors:str='strict') -> None: + bytes = sys.stdin.buffer.read() + data = codecs.decode(bytes, encoding, errors) + super().__init__(data) diff --git a/runtime/Python3/src/antlr4/__init__.py b/runtime/Python3/src/antlr4/__init__.py index 37c834202..42027289e 100644 --- a/runtime/Python3/src/antlr4/__init__.py +++ b/runtime/Python3/src/antlr4/__init__.py @@ -1,6 +1,7 @@ from antlr4.Token import Token from antlr4.InputStream import InputStream from antlr4.FileStream import FileStream +from antlr4.StdinStream import StdinStream from antlr4.BufferedTokenStream import TokenStream from antlr4.CommonTokenStream import CommonTokenStream from antlr4.Lexer import Lexer @@ -17,4 +18,4 @@ from antlr4.tree.Tree import ParseTreeListener, ParseTreeVisitor, ParseTreeWalke from antlr4.error.Errors import RecognitionException, IllegalStateException, NoViableAltException from antlr4.error.ErrorStrategy import BailErrorStrategy from antlr4.error.DiagnosticErrorListener import DiagnosticErrorListener -from antlr4.Utils import str_list \ No newline at end of file +from antlr4.Utils import str_list diff --git a/runtime/Python3/src/antlr4/atn/ParserATNSimulator.py b/runtime/Python3/src/antlr4/atn/ParserATNSimulator.py index d15629252..a3b2c7c14 100644 --- a/runtime/Python3/src/antlr4/atn/ParserATNSimulator.py +++ b/runtime/Python3/src/antlr4/atn/ParserATNSimulator.py @@ -1608,7 +1608,7 @@ class ParserATNSimulator(ATNSimulator): def reportAttemptingFullContext(self, dfa:DFA, conflictingAlts:set, configs:ATNConfigSet, startIndex:int, stopIndex:int): if ParserATNSimulator.debug or ParserATNSimulator.retry_debug: - interval = range(startIndex, stopIndex + 1) + interval = (startIndex, stopIndex + 1) print("reportAttemptingFullContext decision=" + str(dfa.decision) + ":" + str(configs) + ", input=" + self.parser.getTokenStream().getText(interval)) if self.parser is not None: @@ -1616,7 +1616,7 @@ class ParserATNSimulator(ATNSimulator): def reportContextSensitivity(self, dfa:DFA, prediction:int, configs:ATNConfigSet, startIndex:int, stopIndex:int): if ParserATNSimulator.debug or ParserATNSimulator.retry_debug: - interval = range(startIndex, stopIndex + 1) + interval = (startIndex, stopIndex + 1) print("reportContextSensitivity decision=" + str(dfa.decision) + ":" + str(configs) + ", input=" + self.parser.getTokenStream().getText(interval)) if self.parser is not None: @@ -1642,7 +1642,7 @@ class ParserATNSimulator(ATNSimulator): # } # i++; # } - interval = range(startIndex, stopIndex + 1) + interval = (startIndex, stopIndex + 1) print("reportAmbiguity " + str(ambigAlts) + ":" + str(configs) + ", input=" + self.parser.getTokenStream().getText(interval)) if self.parser is not None: diff --git a/runtime/Python3/src/antlr4/atn/SemanticContext.py b/runtime/Python3/src/antlr4/atn/SemanticContext.py index 548d7eaba..d4593195e 100644 --- a/runtime/Python3/src/antlr4/atn/SemanticContext.py +++ b/runtime/Python3/src/antlr4/atn/SemanticContext.py @@ -135,8 +135,8 @@ class PrecedencePredicate(SemanticContext): else: return None - def __cmp__(self, other): - return self.precedence - other.precedence + def __lt__(self, other): + return self.precedence < other.precedence def __hash__(self): return 31 diff --git a/runtime/Swift/Sources/Antlr4/ANTLRInputStream.swift b/runtime/Swift/Sources/Antlr4/ANTLRInputStream.swift index 4267ce132..31c32e107 100644 --- a/runtime/Swift/Sources/Antlr4/ANTLRInputStream.swift +++ b/runtime/Swift/Sources/Antlr4/ANTLRInputStream.swift @@ -2,18 +2,17 @@ /// 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. +/// + +/// /// Vacuum all input from a _java.io.Reader_/_java.io.InputStream_ and then treat it /// like a `char[]` buffer. Can also pass in a _String_ or /// `char[]` to use. /// /// If you need encoding, pass in stream/reader with correct encoding. -/// - +/// public class ANTLRInputStream: CharStream { - public static let READ_BUFFER_SIZE: Int = 1024 - public static let INITIAL_BUFFER_SIZE: Int = 1024 - - /// + /// /// The data being scanned /// internal var data: [Character] @@ -24,9 +23,9 @@ public class ANTLRInputStream: CharStream { internal var n: Int /// - /// 0..n-1 index into string of next char + /// 0...n-1 index into string of next char /// - internal var p: Int = 0 + internal var p = 0 /// /// What is name or source of this char stream? @@ -62,7 +61,7 @@ public class ANTLRInputStream: CharStream { if p >= n { assert(LA(1) == ANTLRInputStream.EOF, "Expected: LA(1)==IntStream.EOF") - throw ANTLRError.illegalState(msg: "annot consume EOF") + throw ANTLRError.illegalState(msg: "cannot consume EOF") } @@ -99,7 +98,7 @@ public class ANTLRInputStream: CharStream { } /// - /// Return the current input symbol index 0..n where n indicates the + /// 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). /// @@ -136,29 +135,21 @@ public class ANTLRInputStream: CharStream { // seek forward, consume until p hits index or n (whichever comes first) index = min(index, n) while p < index { - try consume() + try consume() } } public func getText(_ interval: Interval) -> String { - let start: Int = interval.a - var stop: Int = interval.b - if stop >= n { - stop = n - 1 - } - let count = stop - start + 1; + let start = interval.a if start >= n { return "" } - - return String(data[start ..< (start + count)]) + let stop = min(n, interval.b + 1) + return String(data[start ..< stop]) } public func getSourceName() -> String { - guard let name = name , !name.isEmpty else { - return ANTLRInputStream.UNKNOWN_SOURCE_NAME - } - return name + return name ?? ANTLRInputStream.UNKNOWN_SOURCE_NAME } public func toString() -> String { diff --git a/runtime/Swift/Sources/Antlr4/BufferedTokenStream.swift b/runtime/Swift/Sources/Antlr4/BufferedTokenStream.swift index 82e0fb05a..72cb18fda 100644 --- a/runtime/Swift/Sources/Antlr4/BufferedTokenStream.swift +++ b/runtime/Swift/Sources/Antlr4/BufferedTokenStream.swift @@ -17,7 +17,7 @@ /// channel, such as _org.antlr.v4.runtime.Token#DEFAULT_CHANNEL_ or /// _org.antlr.v4.runtime.Token#HIDDEN_CHANNEL_, use a filtering token stream such a /// _org.antlr.v4.runtime.CommonTokenStream_. -/// +/// public class BufferedTokenStream: TokenStream { /// @@ -30,8 +30,7 @@ public class BufferedTokenStream: TokenStream { /// considered a complete view of the input once _#fetchedEOF_ is set /// to `true`. /// - internal var tokens: Array = Array() - // Array(100 + internal var tokens = [Token]() /// /// The index into _#tokens_ of the current token (next token to @@ -44,7 +43,7 @@ public class BufferedTokenStream: TokenStream { /// see the documentation of _org.antlr.v4.runtime.IntStream_ for a description of /// Initializing Methods. /// - internal var p: Int = -1 + internal var p = -1 /// /// Indicates whether the _org.antlr.v4.runtime.Token#EOF_ token has been fetched from @@ -58,10 +57,10 @@ public class BufferedTokenStream: TokenStream { /// * _#fetch_: The check to prevent adding multiple EOF symbols into /// _#tokens_ is trivial with this field. /// - internal var fetchedEOF: Bool = false + internal var fetchedEOF = false + public init(_ tokenSource: TokenSource) { - self.tokenSource = tokenSource } @@ -135,10 +134,10 @@ public class BufferedTokenStream: TokenStream { @discardableResult internal func sync(_ i: Int) throws -> Bool { assert(i >= 0, "Expected: i>=0") - let n: Int = i - tokens.count + 1 // how many more elements we need? + let n = i - tokens.count + 1 // how many more elements we need? //print("sync("+i+") needs "+n); if n > 0 { - let fetched: Int = try fetch(n) + let fetched = try fetch(n) return fetched >= n } @@ -156,12 +155,12 @@ public class BufferedTokenStream: TokenStream { } for i in 0.. Token { if i < 0 || i >= tokens.count { - let index = tokens.count - 1 - throw ANTLRError.indexOutOfBounds(msg: "token index \(i) out of range 0..\(index)") + throw ANTLRError.indexOutOfBounds(msg: "token index \(i) out of range 0 ..< \(tokens.count)") } return tokens[i] } /// - /// Get all tokens from start..stop inclusively + /// Get all tokens from start...stop inclusively /// public func get(_ start: Int,_ stop: Int) throws -> Array? { var stop = stop @@ -188,12 +186,12 @@ public class BufferedTokenStream: TokenStream { return nil } try lazyInit() - var subset: Array = Array() + var subset = [Token]() if stop >= tokens.count { stop = tokens.count - 1 } for i in start...stop { - let t: Token = tokens[i] + let t = tokens[i] if t.getType() == BufferedTokenStream.EOF { break } @@ -223,14 +221,13 @@ public class BufferedTokenStream: TokenStream { return try LB(-k) } - let i: Int = p + k - 1 + let i = p + k - 1 try sync(i) if i >= tokens.count { // return EOF token // EOF must be last token - return tokens[tokens.count - 1] + return tokens.last! } -// if ( i>range ) range = i; return tokens[i] } @@ -289,7 +286,7 @@ public class BufferedTokenStream: TokenStream { try lazyInit() if start < 0 || start >= tokens.count || stop < 0 || stop >= tokens.count { - throw ANTLRError.indexOutOfBounds(msg: "start \(start) or stop \(stop) not in 0...\(tokens.count - 1)") + throw ANTLRError.indexOutOfBounds(msg: "start \(start) or stop \(stop) not in 0 ..< \(tokens.count)") } if start > stop { @@ -330,7 +327,7 @@ public class BufferedTokenStream: TokenStream { return size() - 1 } - var token: Token = tokens[i] + var token = tokens[i] while token.getChannel() != channel { if token.getType() == BufferedTokenStream.EOF { return i @@ -363,7 +360,7 @@ public class BufferedTokenStream: TokenStream { } while i >= 0 { - let token: Token = tokens[i] + let token = tokens[i] if token.getType() == BufferedTokenStream.EOF || token.getChannel() == channel { return i } @@ -379,45 +376,35 @@ public class BufferedTokenStream: TokenStream { /// 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. /// - public func getHiddenTokensToRight(_ tokenIndex: Int, _ channel: Int) throws -> Array? { + public func getHiddenTokensToRight(_ tokenIndex: Int, _ channel: Int = -1) throws -> [Token]? { try lazyInit() if tokenIndex < 0 || tokenIndex >= tokens.count { - throw ANTLRError.indexOutOfBounds(msg: "\(tokenIndex) not in 0..\(tokens.count - 1)") - + throw ANTLRError.indexOutOfBounds(msg: "\(tokenIndex) not in 0 ..< \(tokens.count)") } - let nextOnChannel: Int = - try nextTokenOnChannel(tokenIndex + 1, Lexer.DEFAULT_TOKEN_CHANNEL) - var to: Int - let from: Int = tokenIndex + 1 + let nextOnChannel = try nextTokenOnChannel(tokenIndex + 1, Lexer.DEFAULT_TOKEN_CHANNEL) + let from = tokenIndex + 1 + let to: Int // if none onchannel to right, nextOnChannel=-1 so set to = last token if nextOnChannel == -1 { to = size() - 1 - } else { + } + else { to = nextOnChannel } return filterForChannel(from, to, channel) } - /// - /// 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. - /// - public func getHiddenTokensToRight(_ tokenIndex: Int) throws -> Array? { - return try getHiddenTokensToRight(tokenIndex, -1) - } - - /// + /// /// 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. /// - public func getHiddenTokensToLeft(_ tokenIndex: Int, _ channel: Int) throws -> Array? { + public func getHiddenTokensToLeft(_ tokenIndex: Int, _ channel: Int = -1) throws -> [Token]? { try lazyInit() if tokenIndex < 0 || tokenIndex >= tokens.count { - throw ANTLRError.indexOutOfBounds(msg: "\(tokenIndex) not in 0..\(tokens.count - 1)") + throw ANTLRError.indexOutOfBounds(msg: "\(tokenIndex) not in 0 ..< \(tokens.count)") } if tokenIndex == 0 { @@ -425,26 +412,16 @@ public class BufferedTokenStream: TokenStream { return nil } - let prevOnChannel: Int = - try previousTokenOnChannel(tokenIndex - 1, Lexer.DEFAULT_TOKEN_CHANNEL) + let prevOnChannel = try previousTokenOnChannel(tokenIndex - 1, Lexer.DEFAULT_TOKEN_CHANNEL) if prevOnChannel == tokenIndex - 1 { return nil } // if none onchannel to left, prevOnChannel=-1 then from=0 - let from: Int = prevOnChannel + 1 - let to: Int = tokenIndex - 1 - + let from = prevOnChannel + 1 + let to = tokenIndex - 1 return filterForChannel(from, to, channel) } - /// - /// 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. - /// - public func getHiddenTokensToLeft(_ tokenIndex: Int) throws -> [Token]? { - return try getHiddenTokensToLeft(tokenIndex, -1) - } - internal func filterForChannel(_ from: Int, _ to: Int, _ channel: Int) -> [Token]? { var hidden = [Token]() for t in tokens[from...to] { @@ -478,17 +455,13 @@ public class BufferedTokenStream: TokenStream { public func getText(_ interval: Interval) throws -> String { let start = interval.a - var stop = interval.b - if start < 0 || stop < 0 { + if start < 0 { return "" } try fill() - if stop >= tokens.count { - stop = tokens.count - 1 - } - + let stop = min(tokens.count, interval.b + 1) var buf = "" - for t in tokens[start...stop] { + for t in tokens[start ..< stop] { if t.getType() == BufferedTokenStream.EOF { break } diff --git a/runtime/Swift/Sources/Antlr4/ListTokenSource.swift b/runtime/Swift/Sources/Antlr4/ListTokenSource.swift index 681e7aa9d..f082452cc 100644 --- a/runtime/Swift/Sources/Antlr4/ListTokenSource.swift +++ b/runtime/Swift/Sources/Antlr4/ListTokenSource.swift @@ -79,10 +79,10 @@ public class ListTokenSource: TokenSource { else if let eofToken = eofToken { return eofToken.getCharPositionInLine() } - else if tokens.count > 0 { + else if !tokens.isEmpty { // have to calculate the result from the line/column of the previous // token, along with the text of the token. - let lastToken = tokens[tokens.count - 1] + let lastToken = tokens.last! if let tokenText = lastToken.getText() { if let lastNewLine = tokenText.lastIndex(of: "\n") { @@ -93,10 +93,11 @@ public class ListTokenSource: TokenSource { lastToken.getStopIndex() - lastToken.getStartIndex() + 1) } - - // only reach this if tokens is empty, meaning EOF occurs at the first - // position in the input - return 0 + else { + // only reach this if tokens is empty, meaning EOF occurs at the first + // position in the input + return 0 + } } public func nextToken() -> Token { @@ -130,33 +131,32 @@ public class ListTokenSource: TokenSource { public func getLine() -> Int { if i < tokens.count { return tokens[i].getLine() - } else { - if let eofToken = eofToken { - return eofToken.getLine() - } else { - if tokens.count > 0 { - // have to calculate the result from the line/column of the previous - // token, along with the text of the token. - let lastToken = tokens[tokens.count - 1] - var line = lastToken.getLine() + } + else if let eofToken = eofToken { + return eofToken.getLine() + } + else if !tokens.isEmpty { + // have to calculate the result from the line/column of the previous + // token, along with the text of the token. + let lastToken = tokens.last! + var line = lastToken.getLine() - if let tokenText = lastToken.getText() { - for c in tokenText { - if c == "\n" { - line += 1 - } - } + if let tokenText = lastToken.getText() { + for c in tokenText { + if c == "\n" { + line += 1 } - - // if no text is available, assume the token did not contain any newline characters. - return line } } - } - // only reach this if tokens is empty, meaning EOF occurs at the first - // position in the input - return 1 + // if no text is available, assume the token did not contain any newline characters. + return line + } + else { + // only reach this if tokens is empty, meaning EOF occurs at the first + // position in the input + return 1 + } } public func getInputStream() -> CharStream? { @@ -166,8 +166,8 @@ public class ListTokenSource: TokenSource { else if let eofToken = eofToken { return eofToken.getInputStream() } - else if tokens.count > 0 { - return tokens[tokens.count - 1].getInputStream() + else if !tokens.isEmpty { + return tokens.last!.getInputStream() } // no input stream information is available diff --git a/runtime/Swift/Sources/Antlr4/Parser.swift b/runtime/Swift/Sources/Antlr4/Parser.swift index e5ff3fd15..1f70f2eea 100644 --- a/runtime/Swift/Sources/Antlr4/Parser.swift +++ b/runtime/Swift/Sources/Antlr4/Parser.swift @@ -8,7 +8,21 @@ import Foundation -/// +/// +/// This field maps from the serialized ATN string to the deserialized _org.antlr.v4.runtime.atn.ATN_ with +/// bypass alternatives. +/// +/// - SeeAlso: `ATNDeserializationOptions.generateRuleBypassTransitions` +/// +private var bypassAltsAtnCache = [String: ATN]() + +/// +/// mutex for bypassAltsAtnCache updates +/// +private let bypassAltsAtnCacheMutex = Mutex() + + +/// /// This is all the parsing support code essentially; most of it is error recovery stuff. /// open class Parser: Recognizer { @@ -58,25 +72,6 @@ open class Parser: Recognizer { } } - /// - /// mutex for bypassAltsAtnCache updates - /// - private let bypassAltsAtnCacheMutex = Mutex() - - /// - /// mutex for decisionToDFA updates - /// - private let decisionToDFAMutex = Mutex() - - /// - /// This field maps from the serialized ATN string to the deserialized _org.antlr.v4.runtime.atn.ATN_ with - /// bypass alternatives. - /// - /// - SeeAlso: org.antlr.v4.runtime.atn.ATNDeserializationOptions#isGenerateRuleBypassTransitions() - /// - private let bypassAltsAtnCache: HashMap = HashMap() - - /// /// The error handling strategy for the parser. The default value is a new /// instance of _org.antlr.v4.runtime.DefaultErrorStrategy_. @@ -417,23 +412,21 @@ open class Parser: Recognizer { /// /// The ATN with bypass alternatives is expensive to create so we create it /// lazily. - /// - /// - Throws: _ANTLRError.unsupportedOperation_ if the current parser does not - /// implement the _#getSerializedATN()_ method. - /// + /// public func getATNWithBypassAlts() -> ATN { let serializedAtn = getSerializedATN() - var result = bypassAltsAtnCache[serializedAtn] - bypassAltsAtnCacheMutex.synchronized { [unowned self] in - if result == nil { - let deserializationOptions = ATNDeserializationOptions() - try! deserializationOptions.setGenerateRuleBypassTransitions(true) - result = try! ATNDeserializer(deserializationOptions).deserialize(Array(serializedAtn)) - self.bypassAltsAtnCache[serializedAtn] = result! + return bypassAltsAtnCacheMutex.synchronized { + if let cachedResult = bypassAltsAtnCache[serializedAtn] { + return cachedResult } + + var opts = ATNDeserializationOptions() + opts.generateRuleBypassTransitions = true + let result = try! ATNDeserializer(opts).deserialize(Array(serializedAtn)) + bypassAltsAtnCache[serializedAtn] = result + return result } - return result! } /// @@ -965,18 +958,13 @@ open class Parser: Recognizer { /// For debugging and other purposes. public func getDFAStrings() -> [String] { - var s = [String]() - guard let _interp = _interp else { - return s + guard let _interp = _interp else { + return [] } - decisionToDFAMutex.synchronized { [unowned self] in - for d in 0..<_interp.decisionToDFA.count { - let dfa = _interp.decisionToDFA[d] - s.append(dfa.toString(self.getVocabulary())) - } - + let vocab = getVocabulary() + return _interp.decisionToDFA.map { + $0.toString(vocab) } - return s } /// For debugging and other purposes. @@ -984,19 +972,16 @@ open class Parser: Recognizer { guard let _interp = _interp else { return } - decisionToDFAMutex.synchronized { [unowned self] in - var seenOne = false - - for dfa in _interp.decisionToDFA { - if !dfa.states.isEmpty { - if seenOne { - print("") - } - print("Decision \(dfa.decision):") - - print(dfa.toString(self.getVocabulary()), terminator: "") - seenOne = true + var seenOne = false + let vocab = getVocabulary() + for dfa in _interp.decisionToDFA { + if !dfa.states.isEmpty { + if seenOne { + print("") } + print("Decision \(dfa.decision):") + print(dfa.toString(vocab), terminator: "") + seenOne = true } } } diff --git a/runtime/Swift/Sources/Antlr4/UnbufferedTokenStream.swift b/runtime/Swift/Sources/Antlr4/UnbufferedTokenStream.swift index e69affed7..3f3dcc0cb 100644 --- a/runtime/Swift/Sources/Antlr4/UnbufferedTokenStream.swift +++ b/runtime/Swift/Sources/Antlr4/UnbufferedTokenStream.swift @@ -12,22 +12,22 @@ public class UnbufferedTokenStream: TokenStream { /// we keep adding to buffer. Otherwise, _#consume consume()_ resets so /// we start filling at index 0 again. /// - internal var tokens: [Token] + internal var tokens = [Token]() /// - /// The number of tokens currently in _#tokens tokens_. + /// The number of tokens currently in `self.tokens`. /// - /// This is not the buffer capacity, that's `tokens.length`. + /// This is not the buffer capacity, that's `self.tokens.count`. /// - internal var n: Int + internal var n = 0 /// - /// 0..n-1 index into _#tokens tokens_ of next token. + /// `0...n-1` index into `self.tokens` of next token. /// /// The `LT(1)` token is `tokens[p]`. If `p == n`, we are /// out of buffered tokens. /// - internal var p: Int = 0 + internal var p = 0 /// /// Count up with _#mark mark()_ and down with @@ -35,7 +35,7 @@ public class UnbufferedTokenStream: TokenStream { /// `numMarkers` reaches 0 and we reset the buffer. Copy /// `tokens[p]..tokens[n-1]` to `tokens[0]..tokens[(n-1)-p]`. /// - internal var numMarkers: Int = 0 + internal var numMarkers = 0 /// /// This is the `LT(-1)` token for the current position. @@ -56,24 +56,18 @@ public class UnbufferedTokenStream: TokenStream { /// This value is used to set the token indexes if the stream provides tokens /// that implement _org.antlr.v4.runtime.WritableToken_. /// - internal var currentTokenIndex: Int = 0 + internal var currentTokenIndex = 0 - public convenience init(_ tokenSource: TokenSource) throws { - try self.init(tokenSource, 256) - } - //TODO: bufferSize don't be use - public init(_ tokenSource: TokenSource, _ bufferSize: Int) throws { + + public init(_ tokenSource: TokenSource) throws { self.tokenSource = tokenSource - //tokens = [Token](count: bufferSize, repeatedValue: Token) ; - tokens = [Token]() - n = 0 try fill(1) // prime the pump } public func get(_ i: Int) throws -> Token { // get absolute index - let bufferStartIndex: Int = getBufferStartIndex() + let bufferStartIndex = getBufferStartIndex() if i < bufferStartIndex || i >= bufferStartIndex + n { throw ANTLRError.indexOutOfBounds(msg: "get(\(i)) outside buffer: \(bufferStartIndex)..\(bufferStartIndex + n)") } @@ -103,7 +97,7 @@ public class UnbufferedTokenStream: TokenStream { public func LA(_ i: Int) throws -> Int { - return try LT(i)!.getType() + return try LT(i)!.getType() } @@ -184,8 +178,8 @@ public class UnbufferedTokenStream: TokenStream { //tokens = Arrays.copyOf(tokens, tokens.length * 2); } - if t is WritableToken { - (t as! WritableToken).setTokenIndex(getBufferStartIndex() + n) + if let wt = t as? WritableToken { + wt.setTokenIndex(getBufferStartIndex() + n) } tokens[n] = t @@ -205,14 +199,14 @@ public class UnbufferedTokenStream: TokenStream { lastTokenBufferStart = lastToken } - let mark: Int = -numMarkers - 1 + let mark = -numMarkers - 1 numMarkers += 1 return mark } public func release(_ marker: Int) throws { - let expectedMark: Int = -numMarkers + let expectedMark = -numMarkers if marker != expectedMark { throw ANTLRError.illegalState(msg: "release() called with an invalid marker.") } @@ -224,7 +218,6 @@ public class UnbufferedTokenStream: TokenStream { // Copy tokens[p]..tokens[n-1] to tokens[0]..tokens[(n-1)-p], reset ptrs // p is last valid token; move nothing if p==n as we have no valid char tokens = Array(tokens[p ... n - 1]) - //System.arraycopy(tokens, p, tokens, 0, n - p); // shift n-p tokens from p to 0 n = n - p p = 0 } @@ -251,16 +244,14 @@ public class UnbufferedTokenStream: TokenStream { index = min(index, getBufferStartIndex() + n - 1) } - let bufferStartIndex: Int = getBufferStartIndex() - let i: Int = index - bufferStartIndex + let bufferStartIndex = getBufferStartIndex() + let i = index - bufferStartIndex if i < 0 { throw ANTLRError.illegalState(msg: "cannot seek to negative index \(index)") - } else { - if i >= n { - throw ANTLRError.unsupportedOperation(msg: "seek to index outside buffer: \(index) not in \(bufferStartIndex)..\(bufferStartIndex + n)") - - } + } + else if i >= n { + throw ANTLRError.unsupportedOperation(msg: "seek to index outside buffer: \(index) not in \(bufferStartIndex)..<\(bufferStartIndex + n)") } p = i @@ -290,7 +281,7 @@ public class UnbufferedTokenStream: TokenStream { let start = interval.a let stop = interval.b if start < bufferStartIndex || stop > bufferStopIndex { - throw ANTLRError.unsupportedOperation(msg: "interval \(interval) not in token buffer window: \(bufferStartIndex)..bufferStopIndex)") + throw ANTLRError.unsupportedOperation(msg: "interval \(interval) not in token buffer window: \(bufferStartIndex)...\(bufferStopIndex)") } let a = start - bufferStartIndex diff --git a/runtime/Swift/Sources/Antlr4/atn/ATN.swift b/runtime/Swift/Sources/Antlr4/atn/ATN.swift index 7422db97f..a963c28ef 100644 --- a/runtime/Swift/Sources/Antlr4/atn/ATN.swift +++ b/runtime/Swift/Sources/Antlr4/atn/ATN.swift @@ -40,8 +40,7 @@ public class ATN { /// /// For lexer ATNs, this maps the rule index to the resulting token type. /// For parser ATNs, this maps the rule index to the generated bypass token - /// type if the - /// _org.antlr.v4.runtime.atn.ATNDeserializationOptions#isGenerateRuleBypassTransitions_ + /// type if the `ATNDeserializationOptions.generateRuleBypassTransitions` /// deserialization option was specified; otherwise, this is `null`. /// public final var ruleToTokenType: [Int]! diff --git a/runtime/Swift/Sources/Antlr4/atn/ATNConfigSet.swift b/runtime/Swift/Sources/Antlr4/atn/ATNConfigSet.swift index 78901e6ac..66e650237 100644 --- a/runtime/Swift/Sources/Antlr4/atn/ATNConfigSet.swift +++ b/runtime/Swift/Sources/Antlr4/atn/ATNConfigSet.swift @@ -303,7 +303,7 @@ public class ATNConfigSet: Hashable, CustomStringConvertible { public final func getConflictingAltSubsets() -> [BitSet] { let length = configs.count - let configToAlts = HashMap(count: length) + var configToAlts = [Int: BitSet]() for i in 0.. HashMap { + public final func getStateToAltMap() -> [ATNState: BitSet] { let length = configs.count - let m = HashMap(count: length) + var m = [ATNState: BitSet]() for i in 0..?,_ parser: Parser,_ _outerContext: ParserRuleContext!) throws -> ATNConfigSet { let configSet = ATNConfigSet(fullCtx) - let statesFromAlt1 = HashMap(count: configs.count) + var statesFromAlt1 = [Int: PredictionContext]() for config in configs { // handle alt 1 first if config.alt != 1 { diff --git a/runtime/Swift/Sources/Antlr4/atn/ATNDeserializationOptions.swift b/runtime/Swift/Sources/Antlr4/atn/ATNDeserializationOptions.swift index 7c5989ccb..135e90557 100644 --- a/runtime/Swift/Sources/Antlr4/atn/ATNDeserializationOptions.swift +++ b/runtime/Swift/Sources/Antlr4/atn/ATNDeserializationOptions.swift @@ -4,73 +4,7 @@ /// can be found in the LICENSE.txt file in the project root. /// - - -/// -/// -/// - Sam Harwell -/// - -public class ATNDeserializationOptions { - - static let defaultOptions: ATNDeserializationOptions = { - - let defaultOptions = ATNDeserializationOptions() - defaultOptions.makeReadOnly() - return defaultOptions - - }() - - - private var readOnly: Bool = false - private var verifyATN: Bool - private var generateRuleBypassTransitions: Bool - - public init() { - self.verifyATN = true - self.generateRuleBypassTransitions = false - } - - public init(_ options: ATNDeserializationOptions) { - self.verifyATN = options.verifyATN - self.generateRuleBypassTransitions = options.generateRuleBypassTransitions - } - - - public static func getDefaultOptions() -> ATNDeserializationOptions { - return defaultOptions - } - - public final func isReadOnly() -> Bool { - return readOnly - } - - public final func makeReadOnly() { - readOnly = true - } - - public final func isVerifyATN() -> Bool { - return verifyATN - } - - public final func setVerifyATN(_ verifyATN: Bool) throws { - try throwIfReadOnly() - self.verifyATN = verifyATN - } - - public final func isGenerateRuleBypassTransitions() -> Bool { - return generateRuleBypassTransitions - } - - public final func setGenerateRuleBypassTransitions(_ generateRuleBypassTransitions: Bool) throws { - try throwIfReadOnly() - self.generateRuleBypassTransitions = generateRuleBypassTransitions - } - - internal func throwIfReadOnly() throws { - if isReadOnly() { - throw ANTLRError.illegalState(msg: "This object is readonly") - - } - } +public struct ATNDeserializationOptions { + public var verifyATN = true + public var generateRuleBypassTransitions = false } diff --git a/runtime/Swift/Sources/Antlr4/atn/ATNDeserializer.swift b/runtime/Swift/Sources/Antlr4/atn/ATNDeserializer.swift index 7e65864f9..65b02efc6 100644 --- a/runtime/Swift/Sources/Antlr4/atn/ATNDeserializer.swift +++ b/runtime/Swift/Sources/Antlr4/atn/ATNDeserializer.swift @@ -60,7 +60,7 @@ public class ATNDeserializer { private let deserializationOptions: ATNDeserializationOptions public init(_ deserializationOptions: ATNDeserializationOptions? = nil) { - self.deserializationOptions = deserializationOptions ?? ATNDeserializationOptions.getDefaultOptions() + self.deserializationOptions = deserializationOptions ?? ATNDeserializationOptions() } /// @@ -667,13 +667,13 @@ public class ATNDeserializer { private func finalizeATN(_ atn: ATN) throws { markPrecedenceDecisions(atn) - if deserializationOptions.isVerifyATN() { + if deserializationOptions.verifyATN { try verifyATN(atn) } - if deserializationOptions.isGenerateRuleBypassTransitions() && atn.grammarType == ATNType.parser { + if deserializationOptions.generateRuleBypassTransitions && atn.grammarType == ATNType.parser { try generateRuleBypassTransitions(atn) - if deserializationOptions.isVerifyATN() { + if deserializationOptions.verifyATN { // reverify after modification try verifyATN(atn) } diff --git a/runtime/Swift/Sources/Antlr4/atn/ATNSimulator.swift b/runtime/Swift/Sources/Antlr4/atn/ATNSimulator.swift index b67926c12..04af4bf1b 100644 --- a/runtime/Swift/Sources/Antlr4/atn/ATNSimulator.swift +++ b/runtime/Swift/Sources/Antlr4/atn/ATNSimulator.swift @@ -75,11 +75,10 @@ open class ATNSimulator { open func getCachedContext(_ context: PredictionContext) -> PredictionContext { //TODO: synced (sharedContextCache!) //synced (sharedContextCache!) { - let visited = HashMap() - + var visited = [PredictionContext: PredictionContext]() return PredictionContext.getCachedContext(context, sharedContextCache, - visited) + &visited) } public static func edgeFactory(_ atn: ATN, diff --git a/runtime/Swift/Sources/Antlr4/atn/LexerATNSimulator.swift b/runtime/Swift/Sources/Antlr4/atn/LexerATNSimulator.swift index 7f84feba4..36858e2af 100644 --- a/runtime/Swift/Sources/Antlr4/atn/LexerATNSimulator.swift +++ b/runtime/Swift/Sources/Antlr4/atn/LexerATNSimulator.swift @@ -711,7 +711,7 @@ open class LexerATNSimulator: ATNSimulator { return dfaStatesMutex.synchronized { if let existing = dfa.states[proposed] { - return existing! + return existing } let newState = proposed diff --git a/runtime/Swift/Sources/Antlr4/atn/LookupDictionary.swift b/runtime/Swift/Sources/Antlr4/atn/LookupDictionary.swift index 1f8e1e21e..cd0af9f54 100644 --- a/runtime/Swift/Sources/Antlr4/atn/LookupDictionary.swift +++ b/runtime/Swift/Sources/Antlr4/atn/LookupDictionary.swift @@ -19,10 +19,9 @@ public enum LookupDictionaryType: Int { } public struct LookupDictionary { - private var type: LookupDictionaryType -// private var cache: HashMap = HashMap() -// - private var cache: HashMap = HashMap() + private let type: LookupDictionaryType + private var cache = [Int: ATNConfig]() + public init(type: LookupDictionaryType = LookupDictionaryType.lookup) { self.type = type } @@ -48,82 +47,41 @@ public struct LookupDictionary { return true } - - let same: Bool = - lhs.state.stateNumber == rhs.state.stateNumber && + return + lhs.state.stateNumber == rhs.state.stateNumber && lhs.alt == rhs.alt && lhs.semanticContext == rhs.semanticContext - - return same - - } else { + } + else { //Ordered return lhs == rhs } } -// public mutating func getOrAdd(config: ATNConfig) -> ATNConfig { -// -// let h = hash(config) -// -// if let configList = cache[h] { -// let length = configList.count -// for i in 0.. ATNConfig { - - let h = hash(config) - - if let configList = cache[h] { - return configList - } else { - cache[h] = config - } - - return config + public mutating func getOrAdd(_ config: ATNConfig) -> ATNConfig { + let h = hash(config) + if let configList = cache[h] { + return configList } + else { + cache[h] = config + } + + return config + } + public var isEmpty: Bool { return cache.isEmpty } -// public func contains(config: ATNConfig) -> Bool { -// -// let h = hash(config) -// if let configList = cache[h] { -// for c in configList { -// if equal(c, config) { -// return true -// } -// } -// } -// -// return false -// -// } public func contains(_ config: ATNConfig) -> Bool { - let h = hash(config) - if let _ = cache[h] { - return true - } - - return false - + return cache[h] != nil } + public mutating func removeAll() { - cache.clear() + cache.removeAll() } } diff --git a/runtime/Swift/Sources/Antlr4/atn/ParserATNSimulator.swift b/runtime/Swift/Sources/Antlr4/atn/ParserATNSimulator.swift index 4db2bd3cd..4ef7f5f28 100644 --- a/runtime/Swift/Sources/Antlr4/atn/ParserATNSimulator.swift +++ b/runtime/Swift/Sources/Antlr4/atn/ParserATNSimulator.swift @@ -255,7 +255,7 @@ open class ParserATNSimulator: ATNSimulator { public final var decisionToDFA: [DFA] - /// + /// /// SLL, LL, or LL + exact ambig detection? /// @@ -2013,7 +2013,7 @@ open class ParserATNSimulator: ATNSimulator { return dfaStatesMutex.synchronized { if let existing = dfa.states[D] { - return existing! + return existing } D.stateNumber = dfa.states.count diff --git a/runtime/Swift/Sources/Antlr4/atn/PredictionContext.swift b/runtime/Swift/Sources/Antlr4/atn/PredictionContext.swift index c23cad0c0..376088905 100644 --- a/runtime/Swift/Sources/Antlr4/atn/PredictionContext.swift +++ b/runtime/Swift/Sources/Antlr4/atn/PredictionContext.swift @@ -580,71 +580,67 @@ public class PredictionContext: Hashable, CustomStringConvertible { public static func getCachedContext( _ context: PredictionContext, _ contextCache: PredictionContextCache, - _ visited: HashMap) -> PredictionContext { - if context.isEmpty() { + _ visited: inout [PredictionContext: PredictionContext]) -> PredictionContext { + if context.isEmpty() { + return context + } + + if let visitedContext = visited[context] { + return visitedContext + } + + if let cachedContext = contextCache.get(context) { + visited[context] = cachedContext + return cachedContext + } + + var changed = false + var parents = [PredictionContext?](repeating: nil, count: context.size()) + let length = parents.count + for i in 0.. [PredictionContext] { var nodes = [PredictionContext]() - let visited = HashMap() - getAllContextNodes_(context, &nodes, visited) + var visited = [PredictionContext: PredictionContext]() + getAllContextNodes_(context, &nodes, &visited) return nodes } - public static func getAllContextNodes_(_ context: PredictionContext?, - _ nodes: inout [PredictionContext], - _ visited: HashMap) { + private static func getAllContextNodes_(_ context: PredictionContext?, + _ nodes: inout [PredictionContext], + _ visited: inout [PredictionContext: PredictionContext]) { guard let context = context, visited[context] == nil else { return } @@ -667,7 +663,7 @@ public class PredictionContext: Hashable, CustomStringConvertible { nodes.append(context) let length = context.size() for i in 0.. = - HashMap() + private var cache = [PredictionContext: PredictionContext]() + public init() { } - /// + + /// /// Add a context to the cache and return it. If the context already exists, /// return that one instead and do not add a new context to the cache. /// Protect shared cache from unsafe thread access. @@ -27,10 +27,9 @@ public final class PredictionContextCache { if ctx === PredictionContext.EMPTY { return PredictionContext.EMPTY } - let existing: PredictionContext? = cache[ctx] - if existing != nil { + if let existing = cache[ctx] { // print(name+" reuses "+existing); - return existing! + return existing } cache[ctx] = ctx return ctx diff --git a/runtime/Swift/Sources/Antlr4/atn/PredictionMode.swift b/runtime/Swift/Sources/Antlr4/atn/PredictionMode.swift index 2bbd71cd2..31db58404 100644 --- a/runtime/Swift/Sources/Antlr4/atn/PredictionMode.swift +++ b/runtime/Swift/Sources/Antlr4/atn/PredictionMode.swift @@ -493,7 +493,7 @@ public enum PredictionMode { /// map[c._org.antlr.v4.runtime.atn.ATNConfig#state state_] U= c._org.antlr.v4.runtime.atn.ATNConfig#alt alt_ /// /// - public static func getStateToAltMap(_ configs: ATNConfigSet) -> HashMap { + public static func getStateToAltMap(_ configs: ATNConfigSet) -> [ATNState: BitSet] { return configs.getStateToAltMap() } diff --git a/runtime/Swift/Sources/Antlr4/dfa/DFA.swift b/runtime/Swift/Sources/Antlr4/dfa/DFA.swift index 6686f8db1..e384ab3e3 100644 --- a/runtime/Swift/Sources/Antlr4/dfa/DFA.swift +++ b/runtime/Swift/Sources/Antlr4/dfa/DFA.swift @@ -7,20 +7,17 @@ public class DFA: CustomStringConvertible { /// - /// A set of all DFA states. Use _java.util.Map_ so we can get old state back - /// (_java.util.Set_ only allows you to see if it's there). + /// A set of all DFA states. /// + public var states = [DFAState: DFAState]() - public final var states: HashMap = HashMap() - - public /*volatile*/ var s0: DFAState? + public var s0: DFAState? public final var decision: Int /// /// From which ATN state did we create this DFA? - /// - + /// public let atnStartState: DecisionState /// diff --git a/runtime/Swift/Sources/Antlr4/misc/DoubleKeyMap.swift b/runtime/Swift/Sources/Antlr4/misc/DoubleKeyMap.swift index 3f23787c9..36a3ba517 100644 --- a/runtime/Swift/Sources/Antlr4/misc/DoubleKeyMap.swift +++ b/runtime/Swift/Sources/Antlr4/misc/DoubleKeyMap.swift @@ -11,34 +11,36 @@ /// This nested hash table saves creating a single key each time we access /// map; avoids mem creation. /// -public struct DoubleKeyMap { - private var data: HashMap> = HashMap>() +public struct DoubleKeyMap { + private var data = [Key1: [Key2: Value]]() + @discardableResult public mutating func put(_ k1: Key1, _ k2: Key2, _ v: Value) -> Value? { - var data2 = data[k1] - var prev: Value? = nil - if data2 == nil { - data2 = HashMap() - - } else { - prev = data2![k2] + let prev: Value? + if var data2 = data[k1] { + prev = data2[k2] + data2[k2] = v + data[k1] = data2 + } + else { + prev = nil + let data2 = [ + k2: v + ] + data[k1] = data2 } - data2![k2] = v - data[k1] = data2 return prev } - public func get(_ k1: Key1, _ k2: Key2) -> Value? { - + public func get(_ k1: Key1, _ k2: Key2) -> Value? { if let data2 = data[k1] { return data2[k2] } - return nil - + return nil } - public func get(_ k1: Key1) -> HashMap? { + public func get(_ k1: Key1) -> [Key2: Value]? { return data[k1] } } diff --git a/runtime/Swift/Sources/Antlr4/misc/HashMap.swift b/runtime/Swift/Sources/Antlr4/misc/HashMap.swift deleted file mode 100644 index a7cba83f7..000000000 --- a/runtime/Swift/Sources/Antlr4/misc/HashMap.swift +++ /dev/null @@ -1,475 +0,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. -/// - -final class Entry: CustomStringConvertible { - final var key: K - final var value: V - final var next: Entry! - final var hash: Int - - /// - /// Creates new entry. - /// - init(_ h: Int, _ k: K, _ v: V, _ n: Entry!) { - value = v - next = n - key = k - hash = h - } - - final func getKey() -> K { - return key - } - - final func getValue() -> V { - return value - } - - final func setValue(_ newValue: V) -> V { - let oldValue: V = value - value = newValue - return oldValue - } - - final var hashValue: Int { - return key.hashValue - } - - var description: String { return "\(getKey())=\(getValue())" } - -} -func == (lhs: Entry, rhs: Entry) -> Bool { - if lhs === rhs { - return true - } - if lhs.key == rhs.key { - if lhs.value == rhs.value { - return true - } - } - return false -} -func == (lhs: Entry, rhs: Entry) -> Bool { - if lhs === rhs { - return true - } - if lhs.key == rhs.key { - if lhs.value == nil && rhs.value == nil { - return true - } else if lhs.value != nil && rhs.value != nil && lhs.value! == rhs.value! { - return true - } - } - return false -} - - - -public final class HashMap: Sequence -{ - - /// - /// The default initial capacity - MUST be a power of two. - /// - private let DEFAULT_INITIAL_CAPACITY: Int = 16 - - /// - /// The maximum capacity, used if a higher value is implicitly specified - /// by either of the constructors with arguments. - /// MUST be a power of two <= 1<<30. - /// - private let MAXIMUM_CAPACITY: Int = 1 << 30 - - /// - /// The load factor used when none specified in constructor. - /// - private let DEFAULT_LOAD_FACTOR: Float = 0.75 - - /// - /// The table, resized as necessary. Length MUST Always be a power of two. - /// - var table: [Entry?] - - /// - /// The number of key-value mappings contained in this map. - /// - var size: Int = 0 - - /// - /// The next size value at which to resize (capacity * load factor). - /// - - /// - var threshold: Int = 0 - - /// - /// The load factor for the hash table. - /// - /// - - /// - var loadFactor: Float = 0 - - /// - /// The number of times this HashMap has been structurally modified - /// Structural modifications are those that change the number of mappings in - /// the HashMap or otherwise modify its internal structure (e.g., - /// rehash). This field is used to make iterators on Collection-views of - /// the HashMap fail-fast. (See ConcurrentModificationException). - /// - var modCount: Int = 0 - - public init(count: Int) { - var initialCapacity = count - if (count < 0) - { - initialCapacity = DEFAULT_INITIAL_CAPACITY - } - else if (count > MAXIMUM_CAPACITY) - { - initialCapacity = MAXIMUM_CAPACITY - } else { - // Find a power of 2 >= initialCapacity - initialCapacity = 1 - while initialCapacity < count - { - initialCapacity <<= 1 - } - } - - self.loadFactor = DEFAULT_LOAD_FACTOR - threshold = Int(Float(initialCapacity) * loadFactor) - table = [Entry?](repeating: nil, count: initialCapacity) - } - public init() { - self.loadFactor = DEFAULT_LOAD_FACTOR - threshold = Int(Float(DEFAULT_INITIAL_CAPACITY) * DEFAULT_LOAD_FACTOR) - table = [Entry?](repeating: nil, count: DEFAULT_INITIAL_CAPACITY) - } - - static func hash(_ h: Int) -> Int { - var h = h - // This function ensures that hashCodes that differ only by - // constant multiples at each bit position have a bounded - // number of collisions (approximately 8 at default load factor). - h ^= (h >>> 20) ^ (h >>> 12) - return h ^ (h >>> 7) ^ (h >>> 4) - } - - /// - /// Returns index for hash code h. - /// - static func indexFor(_ h: Int, _ length: Int) -> Int { - return h & (length-1) - } - - /// - /// Returns true if this map contains no key-value mappings. - /// - /// - returns: true if this map contains no key-value mappings - /// - public final var isEmpty: Bool { - return size == 0 - } - public final subscript(key: K) -> V? { - get { - return get(key) - } - set { - if newValue == nil { - remove(key) - }else{ - put(key,newValue!) - } - } - } - - public final var count: Int { - return size - } - /// - /// Returns the value to which the specified key is mapped, - /// or `null` if this map contains no mapping for the key. - /// - /// More formally, if this map contains a mapping from a key - /// `k` to a value `v` such that `(key==null ? k==null : - /// key.equals(k))`, then this method returns `v`; otherwise - /// it returns `null`. (There can be at most one such mapping.) - /// - /// A return value of `null` does not necessarily - /// indicate that the map contains no mapping for the key; it's also - /// possible that the map explicitly maps the key to `null`. - /// The _#containsKey containsKey_ operation may be used to - /// distinguish these two cases. - /// - /// - seealso: #put(Object, Object) - /// - public final func get(_ key: K) -> V? { - let hash: Int = HashMap.hash(key.hashValue) - var e = table[HashMap.indexFor(hash, table.count)] - while let eWrap = e { - if eWrap.hash == hash && eWrap.key == key - { - return eWrap.value - } - e = eWrap.next - } - - return nil - } - /// - /// Returns true if this map contains a mapping for the - /// specified key. - /// - /// - parameter key: The key whose presence in this map is to be tested - /// - returns: true if this map contains a mapping for the specified - /// key. - /// - public final func containsKey(_ key: K) -> Bool { - return getEntry(key) != nil - } - - /// - /// Returns the entry associated with the specified key in the - /// HashMap. Returns null if the HashMap contains no mapping - /// for the key. - /// - final func getEntry(_ key: K) -> Entry! { - let hash: Int = HashMap.hash(key.hashValue) - var e = table[HashMap.indexFor(hash, table.count)] - while let eWrap = e { - if eWrap.hash == hash && eWrap.key == key - { - return eWrap - } - e = eWrap.next - } - - return nil - } - - - /// - /// Associates the specified value with the specified key in this map. - /// If the map previously contained a mapping for the key, the old - /// value is replaced. - /// - /// - parameter key: key with which the specified value is to be associated - /// - parameter value: value to be associated with the specified key - /// - returns: the previous value associated with key, or - /// null if there was no mapping for key. - /// (A null return can also indicate that the map - /// previously associated null with key.) - /// - @discardableResult - public final func put(_ key: K, _ value: V) -> V? { - - let hash: Int = HashMap.hash(key.hashValue) - let i: Int = HashMap.indexFor(hash, table.count) - var e = table[i] - while let eWrap = e { - if eWrap.hash == hash && eWrap.key == key { - let oldValue = eWrap.value - eWrap.value = value - return oldValue - } - e = eWrap.next - } - - - modCount += 1 - addEntry(hash, key, value, i) - return nil - } - - /// - /// Adds a new entry with the specified key, value and hash code to - /// the specified bucket. It is the responsibility of this - /// method to resize the table if appropriate. - /// - /// Subclass overrides this to alter the behavior of put method. - /// - final func addEntry(_ hash: Int, _ key: K, _ value: V, _ bucketIndex: Int) { - let e = table[bucketIndex] - table[bucketIndex] = Entry(hash, key, value, e) - let oldSize = size - size += 1 - if oldSize >= threshold { - resize(2 * table.count) - } - } - /// - /// Rehashes the contents of this map into a new array with a - /// larger capacity. This method is called automatically when the - /// number of keys in this map reaches its threshold. - /// - /// If current capacity is MAXIMUM_CAPACITY, this method does not - /// resize the map, but sets threshold to Integer.MAX_VALUE. - /// This has the effect of preventing future calls. - /// - /// - parameter newCapacity: the new capacity, MUST be a power of two; - /// must be greater than current capacity unless current - /// capacity is MAXIMUM_CAPACITY (in which case value - /// is irrelevant). - /// - final func resize(_ newCapacity: Int) { - let oldCapacity: Int = table.count - if oldCapacity == MAXIMUM_CAPACITY { - threshold = Int.max - return - } - - var newTable = [Entry?](repeating: nil, count: newCapacity) - transfer(&newTable) - table = newTable - threshold = Int(Float(newCapacity) * loadFactor) - } - - /// - /// Transfers all entries from current table to newTable. - /// - final func transfer(_ newTable: inout [Entry?]) { - - let newCapacity: Int = newTable.count - let length = table.count - for j in 0..? = e - while let e = eOption { - let next = e.next - let i: Int = HashMap.indexFor(e.hash, newCapacity) - e.next = newTable[i] - newTable[i] = e - eOption = next - } - } - } - } - /// - /// Removes all of the mappings from this map. - /// The map will be empty after this call returns. - /// - public final func clear() { - modCount += 1 - let length = table.count - for i in 0.. V? { - if let e = removeEntryForKey(key) { - return e.value - } - return nil - } - - - final func removeEntryForKey(_ key: K) -> Entry? { - let hash: Int = HashMap.hash(Int(key.hashValue)) - let i = Int(HashMap.indexFor(hash, Int(table.count))) - var prev = table[i] - var e = prev - - while let eWrap = e { - let next = eWrap.next - var _: AnyObject - if eWrap.hash == hash && eWrap.key == key{ - modCount += 1 - size -= 1 - if prev === eWrap - {table[i] = next} - else - {prev?.next = next} - return eWrap - } - prev = eWrap - e = next - } - - return e - } - - public final var values: [V]{ - var valueList: [V] = [V]() - let length = table.count - for j in 0..? = e - while let e = eOption { - let next = e.next - eOption = next - if let eOption = eOption { - valueList.append(eOption.value) - } - - } - } - } - return valueList - } - - public final var keys: [K]{ - var keyList: [K] = [K]() - let length = table.count - for j in 0..? = e - while let e = eOption { - let next = e.next - eOption = next - if let eOption = eOption { - keyList.append(eOption.key ) - } - - } - } - } - return keyList - } - - - public func makeIterator() -> AnyIterator<(K,V)> { - var _next: Entry? // next entry to return - let expectedModCount: Int = modCount // For fast-fail - var index: Int = 0 // current slot - //var current: HashMapEntry // current entry - if size > 0{ // advance to first entry - - while index < table.count && _next == nil - { - _next = table[index] - index += 1 - } - } - - return AnyIterator { - if self.modCount != expectedModCount - { - fatalError("\(#function) ConcurrentModificationException") - } - if let e = _next { - _next = e.next - if _next == nil{ - while index < self.table.count && _next == nil - { - _next = self.table[index] - index += 1 - } - } - //current = e - return (e.getKey(),e.getValue()) - } else { - return nil - } - - } - - } - -} diff --git a/tool-testsuite/pom.xml b/tool-testsuite/pom.xml index f145f0258..5240f6843 100644 --- a/tool-testsuite/pom.xml +++ b/tool-testsuite/pom.xml @@ -26,7 +26,7 @@ org.antlr ST4 - 4.0.8 + 4.1-SNAPSHOT test diff --git a/tool/pom.xml b/tool/pom.xml index 78da0b47c..b389d44d2 100644 --- a/tool/pom.xml +++ b/tool/pom.xml @@ -29,7 +29,7 @@ org.antlr ST4 - 4.0.8 + 4.1 org.abego.treelayout @@ -44,7 +44,7 @@ com.ibm.icu icu4j - 58.2 + 61.1 diff --git a/tool/resources/org/antlr/v4/tool/templates/codegen/Cpp/Cpp.stg b/tool/resources/org/antlr/v4/tool/templates/codegen/Cpp/Cpp.stg index 6342b660e..4c367dda5 100644 --- a/tool/resources/org/antlr/v4/tool/templates/codegen/Cpp/Cpp.stg +++ b/tool/resources/org/antlr/v4/tool/templates/codegen/Cpp/Cpp.stg @@ -510,6 +510,7 @@ LeftRecursiveRuleFunction(currentRule, args, code, locals, ruleCtx, altLabelCtxs size_t parentState = getState(); :: *_localctx = _tracker.createInstance\<\>(_ctx, parentState}>); :: *previousContext = _localctx; + (void)previousContext; // Silence compiler, in case the context is not used by generated code. size_t startState = ; enterRecursionRule(_localctx, , ::Rule, precedence); @@ -542,7 +543,7 @@ public: (antlr4::ParserRuleContext *parent, size_t invokingState); (antlr4::ParserRuleContext *parent, size_t invokingState}>); - () : antlr4::ParserRuleContext() { } + () = default; void copyFrom( *context); using antlr4::ParserRuleContext::copyFrom; diff --git a/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg b/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg index 492c56644..1683a18f8 100644 --- a/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg +++ b/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg @@ -236,9 +236,12 @@ public class extends { public static final int = }; separator=", ", wrap, anchor>; - public static final String[] ruleNames = { - "}; separator=", ", wrap, anchor> - }; + private static String[] makeRuleNames() { + return new String[] { + "}; separator=", ", wrap, anchor> + }; + } + public static final String[] ruleNames = makeRuleNames(); @@ -275,12 +278,18 @@ case : >> vocabulary(literalNames, symbolicNames) ::= << -private static final String[] _LITERAL_NAMES = { - }; null="null", separator=", ", wrap, anchor> -}; -private static final String[] _SYMBOLIC_NAMES = { - }; null="null", separator=", ", wrap, anchor> -}; +private static String[] makeLiteralNames() { + return new String[] { + }; null="null", separator=", ", wrap, anchor> + }; +} +private static final String[] _LITERAL_NAMES = makeLiteralNames(); +private static String[] makeSymbolicNames() { + return new String[] { + }; null="null", separator=", ", wrap, anchor> + }; +} +private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); /** @@ -914,9 +923,12 @@ public class extends { "}; separator=", ", wrap, anchor> }; - public static final String[] ruleNames = { - "}; separator=", ", wrap, anchor> - }; + private static String[] makeRuleNames() { + return new String[] { + "}; separator=", ", wrap, anchor> + }; + } + public static final String[] ruleNames = makeRuleNames(); diff --git a/tool/resources/org/antlr/v4/tool/templates/codegen/Python2/Python2.stg b/tool/resources/org/antlr/v4/tool/templates/codegen/Python2/Python2.stg index 570f1659f..dcaa4463d 100644 --- a/tool/resources/org/antlr/v4/tool/templates/codegen/Python2/Python2.stg +++ b/tool/resources/org/antlr/v4/tool/templates/codegen/Python2/Python2.stg @@ -749,6 +749,10 @@ import sys >> Lexer(lexer, atn, actionFuncs, sempredFuncs, superClass) ::= << + +from . import + + diff --git a/tool/resources/org/antlr/v4/tool/templates/codegen/Python3/Python3.stg b/tool/resources/org/antlr/v4/tool/templates/codegen/Python3/Python3.stg index 34e525b85..8e03da79f 100644 --- a/tool/resources/org/antlr/v4/tool/templates/codegen/Python3/Python3.stg +++ b/tool/resources/org/antlr/v4/tool/templates/codegen/Python3/Python3.stg @@ -119,7 +119,10 @@ Parser(parser, funcs, atn, sempredFuncs, superClass) ::= << Parser_(parser, funcs, atn, sempredFuncs, ctor, superClass) ::= << -from . import +if __name__ is not None and "." in __name__: + from . import +else: + from import @@ -756,7 +759,13 @@ import sys >> Lexer(lexer, atn, actionFuncs, sempredFuncs, superClass) ::= << + +if __name__ is not None and "." in __name__: + from . import +else: + from import + class (Lexer): diff --git a/tool/src/org/antlr/v4/codegen/target/Python2Target.java b/tool/src/org/antlr/v4/codegen/target/Python2Target.java index 3fc6a3541..28dfaae60 100644 --- a/tool/src/org/antlr/v4/codegen/target/Python2Target.java +++ b/tool/src/org/antlr/v4/codegen/target/Python2Target.java @@ -24,27 +24,28 @@ import java.util.Set; */ public class Python2Target extends Target { protected static final String[] python2Keywords = { - "abs", "all", "any", "apply", "as", - "bin", "bool", "buffer", "bytearray", - "callable", "chr", "classmethod", "coerce", "compile", "complex", - "del", "delattr", "dict", "dir", "divmod", - "enumerate", "eval", "execfile", - "file", "filter", "float", "format", "frozenset", - "getattr", "globals", + "abs", "all", "and", "any", "apply", "as", "assert", + "bin", "bool", "break", "buffer", "bytearray", + "callable", "chr", "class", "classmethod", "coerce", "compile", "complex", "continue", + "def", "del", "delattr", "dict", "dir", "divmod", + "elif", "else", "enumerate", "eval", "except", "exec", "execfile", + "file", "filter", "finally", "float", "for", "format", "from", "frozenset", + "getattr", "global", "globals", "hasattr", "hash", "help", "hex", - "id", "input", "int", "intern", "isinstance", "issubclass", "iter", - "len", "list", "locals", - "map", "max", "min", "next", + "id", "if", "import", "in", "input", "int", "intern", "is", "isinstance", "issubclass", "iter", + "lambda", "len", "list", "locals", + "map", "max", "min", "next", "not", "memoryview", - "object", "oct", "open", "ord", - "pow", "print", "property", - "range", "raw_input", "reduce", "reload", "repr", "return", "reversed", "round", + "object", "oct", "open", "or", "ord", + "pass", "pow", "print", "property", + "raise", "range", "raw_input", "reduce", "reload", "repr", "return", "reversed", "round", "set", "setattr", "slice", "sorted", "staticmethod", "str", "sum", "super", - "tuple", "type", + "try", "tuple", "type", "unichr", "unicode", "vars", - "with", + "while", "with", "xrange", + "yield", "zip", "__import__", "True", "False", "None" diff --git a/tool/src/org/antlr/v4/codegen/target/Python3Target.java b/tool/src/org/antlr/v4/codegen/target/Python3Target.java index 388269a73..1dffc4e42 100644 --- a/tool/src/org/antlr/v4/codegen/target/Python3Target.java +++ b/tool/src/org/antlr/v4/codegen/target/Python3Target.java @@ -24,26 +24,27 @@ import java.util.Set; */ public class Python3Target extends Target { protected static final String[] python3Keywords = { - "abs", "all", "any", "apply", "as", - "bin", "bool", "buffer", "bytearray", - "callable", "chr", "classmethod", "coerce", "compile", "complex", - "del", "delattr", "dict", "dir", "divmod", - "enumerate", "eval", "execfile", - "file", "filter", "float", "format", "frozenset", - "getattr", "globals", + "abs", "all", "and", "any", "apply", "as", "assert", + "bin", "bool", "break", "buffer", "bytearray", + "callable", "chr", "class", "classmethod", "coerce", "compile", "complex", "continue", + "def", "del", "delattr", "dict", "dir", "divmod", + "elif", "else", "enumerate", "eval", "execfile", "except", + "file", "filter", "finally", "float", "for", "format", "from", "frozenset", + "getattr", "global", "globals", "hasattr", "hash", "help", "hex", - "id", "input", "int", "intern", "isinstance", "issubclass", "iter", - "len", "list", "locals", - "map", "max", "min", "next", - "memoryview", - "object", "oct", "open", "ord", - "pow", "print", "property", - "range", "raw_input", "reduce", "reload", "repr", "return", "reversed", "round", + "id", "if", "import", "in", "input", "int", "intern", "is", "isinstance", "issubclass", "iter", + "lambda", "len", "list", "locals", + "map", "max", "min", "memoryview", + "next", "nonlocal", "not", + "object", "oct", "open", "or", "ord", + "pass", "pow", "print", "property", + "raise", "range", "raw_input", "reduce", "reload", "repr", "return", "reversed", "round", "set", "setattr", "slice", "sorted", "staticmethod", "str", "sum", "super", - "tuple", "type", + "try", "tuple", "type", "unichr", "unicode", "vars", - "with", + "with", "while", + "yield", "zip", "__import__", "True", "False", "None"