Antlr C++ configured

This commit is contained in:
ridethepig 2023-04-28 15:00:58 +08:00
commit c9863dda91
14 changed files with 944 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
build/

6
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,6 @@
{
"clangd.arguments": [
"--compile-commands-dir=${workspaceFolder}/build"
],
"cmake.configureOnOpen": true
}

27
CMakeLists.txt Normal file
View File

@ -0,0 +1,27 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.7)
project(sysy)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_EXPORT_COMPILE_COMMANDS 1) # generate food for clangd
# Include path for ExternalAntlr4Cpp
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
add_definitions(-DANTLR4CPP_STATIC)
# using /MD flag for antlr4_runtime (for Visual C++ compilers only)
set(ANTLR4_WITH_STATIC_CRT OFF)
set(ANTLR4_ZIP_REPOSITORY ${CMAKE_CURRENT_SOURCE_DIR}/tools/antlr4-4.12.0.zip)
include(ExternalAntlr4Cpp)
include_directories(${ANTLR4_INCLUDE_DIRS})
set(ANTLR_EXECUTABLE ${CMAKE_CURRENT_SOURCE_DIR}/tools/antlr-4.12.0-complete.jar)
find_package(ANTLR REQUIRED)
antlr_target(SysY ${CMAKE_CURRENT_SOURCE_DIR}/SysY.g4 VISITOR
PACKAGE antlrSysY
)
include_directories(${ANTLR_SysY_OUTPUT_DIR})
# Custom sources start here
file(GLOB_RECURSE SOURCES "src/*.cpp")
add_executable(sysy ${SOURCES} ${ANTLR_SysY_CXX_OUTPUTS})
target_link_libraries(sysy antlr4_static)

389
SysY.g4 Normal file
View File

@ -0,0 +1,389 @@
grammar SysY;
program
: compUnit
;
compUnit
: (funcDef | decl)+
;
decl
: constDecl
| varDecl
;
constDecl
: CONST_KW bType constDef (COMMA constDef)* SEMICOLON
;
bType
: INT_KW
;
constDef
: IDENT (L_BRACKT constExp R_BRACKT)* ASSIGN constInitVal
;
constInitVal
: constExp
| (L_BRACE (constInitVal (COMMA constInitVal)*)? R_BRACE)
;
varDecl
: bType varDef (COMMA varDef)* SEMICOLON
;
varDef
: IDENT (L_BRACKT constExp R_BRACKT)* (ASSIGN initVal)?
;
initVal
: exp
| (L_BRACE (initVal (COMMA initVal)*)? R_BRACE)
;
funcDef
: funcType IDENT L_PAREN funcFParams? R_PAREN block
;
funcType
: VOID_KW
| INT_KW
;
funcFParams
: funcFParam (COMMA funcFParam)*
;
funcFParam
: bType IDENT (L_BRACKT R_BRACKT (L_BRACKT exp R_BRACKT)*)?
;
block
: L_BRACE blockItem* R_BRACE
;
blockItem
: constDecl
| varDecl
| stmt
;
stmt
: assignStmt
| expStmt
| block
| conditionStmt
| whileStmt
| breakStmt
| continueStmt
| returnStmt
;
assignStmt
: lVal ASSIGN exp SEMICOLON
;
expStmt
: exp? SEMICOLON
;
conditionStmt
: IF_KW L_PAREN cond R_PAREN stmt (ELSE_KW stmt)?
;
whileStmt
: WHILE_KW L_PAREN cond R_PAREN stmt
;
breakStmt
: BREAK_KW SEMICOLON
;
continueStmt
: CONTINUE_KW SEMICOLON
;
returnStmt
: RETURN_KW (exp)? SEMICOLON
;
exp
: addExp
;
cond
: lOrExp
;
lVal
: IDENT (L_BRACKT exp R_BRACKT)*
;
primaryExp
: (L_PAREN exp R_PAREN)
| lVal
| number
;
number
: intConst
;
intConst
: DECIMAL_CONST
| OCTAL_CONST
| HEXADECIMAL_CONST
;
unaryExp
: primaryExp
| callee
| (unaryOp unaryExp)
;
callee
: IDENT L_PAREN funcRParams? R_PAREN
;
unaryOp
: PLUS
| MINUS
| NOT
;
funcRParams
: param (COMMA param)*
;
param
: exp
| STRING
;
mulExp
: unaryExp (mulOp unaryExp)*
; // eliminate left-recursive
mulOp
: MUL
| DIV
| MOD
;
addExp
: mulExp (addOp mulExp)*
; // eliminate left-recursive
addOp
: PLUS
| MINUS
;
relExp
: addExp (relOp addExp)*
; // eliminate left-recursive
relOp
: LT
| GT
| LE
| GE
;
eqExp
: relExp (eqOp relExp)*
;
eqOp
: EQ
| NEQ
;
lAndExp
: eqExp (AND eqExp)*
;
lOrExp
: lAndExp (OR lAndExp)*
;
constExp
: addExp
;
CONST_KW
: 'const'
;
INT_KW
: 'int'
;
VOID_KW
: 'void'
;
IF_KW
: 'if'
;
ELSE_KW
: 'else'
;
WHILE_KW
: 'while'
;
BREAK_KW
: 'break'
;
CONTINUE_KW
: 'continue'
;
RETURN_KW
: 'return'
;
IDENT
: [_a-zA-Z]
| [_a-zA-Z] [_a-zA-Z0-9]+
;
DECIMAL_CONST
: [1-9]
| [1-9] [0-9]+
;
OCTAL_CONST
: '0'
| ('0' [0-7]+)
;
HEXADECIMAL_CONST
: ('0x' | '0X') [a-fA-F0-9]+
;
STRING
: DOUBLE_QUOTE REGULAR_CHAR*? DOUBLE_QUOTE
;
fragment REGULAR_CHAR
: (ESC | .)
;
fragment ESC
: '\\"' | '\\\\'
;
PLUS
: '+'
;
MINUS
: '-'
;
NOT
: '!'
;
MUL
: '*'
;
DIV
: '/'
;
MOD
: '%'
;
ASSIGN
: '='
;
EQ
: '=='
;
NEQ
: '!='
;
LT
: '<'
;
GT
: '>'
;
LE
: '<='
;
GE
: '>='
;
AND
: '&&'
;
OR
: '||'
;
L_PAREN
: '('
;
R_PAREN
: ')'
;
L_BRACE
: '{'
;
R_BRACE
: '}'
;
L_BRACKT
: '['
;
R_BRACKT
: ']'
;
COMMA
: ','
;
SEMICOLON
: ';'
;
DOUBLE_QUOTE
: '"'
;
WS
: [ \r\n\t]+ -> skip
;
LINE_COMMENT
: '//' ~ [\r\n]* -> skip
;
MULTILINE_COMMENT
: '/*' .*? '*/' -> skip
;

View File

@ -0,0 +1,177 @@
cmake_minimum_required(VERSION 3.7)
if(POLICY CMP0114)
cmake_policy(SET CMP0114 NEW)
endif()
include(ExternalProject)
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()
# Ensure that the include dir already exists at configure time (to avoid cmake erroring
# on non-existent include dirs)
file(MAKE_DIRECTORY "${ANTLR4_INCLUDE_DIRS}")
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()
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.12.0.dll)
elseif(APPLE)
set(ANTLR4_RUNTIME_LIBRARIES
${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.dylib)
else()
set(ANTLR4_RUNTIME_LIBRARIES
${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.so)
endif()
endif()
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()
if(NOT DEFINED ANTLR4_WITH_STATIC_CRT)
set(ANTLR4_WITH_STATIC_CRT ON)
endif()
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}
-DDISABLE_WARNINGS:BOOL=ON
# -DCMAKE_CXX_STANDARD:STRING=17 # if desired, compile the runtime with a different C++ standard
# -DCMAKE_CXX_STANDARD:STRING=${CMAKE_CXX_STANDARD} # alternatively, compile the runtime with the same C++ standard as the outer project
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}
-DDISABLE_WARNINGS:BOOL=ON
# -DCMAKE_CXX_STANDARD:STRING=17 # if desired, compile the runtime with a different C++ standard
# -DCMAKE_CXX_STANDARD:STRING=${CMAKE_CXX_STANDARD} # alternatively, compile the runtime with the same C++ standard as the outer project
INSTALL_COMMAND ""
EXCLUDE_FROM_ALL 1)
endif()
# Separate build step as rarely people want both
set(ANTLR4_BUILD_DIR ${ANTLR4_ROOT})
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.14.0")
# CMake 3.14 builds in above's SOURCE_SUBDIR when BUILD_IN_SOURCE is true
set(ANTLR4_BUILD_DIR ${ANTLR4_ROOT}/runtime/Cpp)
endif()
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_BUILD_DIR})
ExternalProject_Add_StepTargets(antlr4_runtime build_static)
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})
target_include_directories(antlr4_static
INTERFACE
${ANTLR4_INCLUDE_DIRS}
)
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_BUILD_DIR})
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})
target_include_directories(antlr4_shared
INTERFACE
${ANTLR4_INCLUDE_DIRS}
)
if(ANTLR4_SHARED_LIBRARIES)
set_target_properties(antlr4_shared PROPERTIES
IMPORTED_IMPLIB ${ANTLR4_SHARED_LIBRARIES})
endif()

124
cmake/FindANTLR.cmake Normal file
View File

@ -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.12.0-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)

View File

@ -0,0 +1,181 @@
set(ANTLR_VERSION @ANTLR_VERSION@)
@PACKAGE_INIT@
if (NOT ANTLR4_CPP_GENERATED_SRC_DIR)
set(ANTLR4_GENERATED_SRC_DIR ${CMAKE_BINARY_DIR}/antlr4_generated_src)
endif()
FIND_PACKAGE(Java COMPONENTS Runtime REQUIRED)
#
# The ANTLR generator will output the following files given the input file f.g4
#
# Input -> f.g4
# Output -> f.h
# -> f.cpp
#
# the following files will only be produced if there is a parser contained
# Flag -visitor active
# Output -> <f>BaseVisitor.h
# -> <f>BaseVisitor.cpp
# -> <f>Visitor.h
# -> <f>Visitor.cpp
#
# Flag -listener active
# Output -> <f>BaseListener.h
# -> <f>BaseListener.cpp
# -> <f>Listener.h
# -> <f>Listener.cpp
#
# See documentation in markup
#
function(antlr4_generate
Antlr4_ProjectTarget
Antlr4_InputFile
Antlr4_GeneratorType
)
set( Antlr4_GeneratedSrcDir ${ANTLR4_GENERATED_SRC_DIR}/${Antlr4_ProjectTarget} )
get_filename_component(Antlr4_InputFileBaseName ${Antlr4_InputFile} NAME_WE )
list( APPEND Antlr4_GeneratorStatusMessage "Common Include-, Source- and Tokenfiles" )
if ( ${Antlr4_GeneratorType} STREQUAL "LEXER")
set(Antlr4_LexerBaseName "${Antlr4_InputFileBaseName}")
set(Antlr4_ParserBaseName "")
else()
if ( ${Antlr4_GeneratorType} STREQUAL "PARSER")
set(Antlr4_LexerBaseName "")
set(Antlr4_ParserBaseName "${Antlr4_InputFileBaseName}")
else()
if ( ${Antlr4_GeneratorType} STREQUAL "BOTH")
set(Antlr4_LexerBaseName "${Antlr4_InputFileBaseName}Lexer")
set(Antlr4_ParserBaseName "${Antlr4_InputFileBaseName}Parser")
else()
message(FATAL_ERROR "The third parameter must be LEXER, PARSER or BOTH")
endif ()
endif ()
endif ()
# Prepare list of generated targets
list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}.tokens" )
list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}.interp" )
list( APPEND DependentTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}.tokens" )
if ( NOT ${Antlr4_LexerBaseName} STREQUAL "" )
list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_LexerBaseName}.h" )
list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_LexerBaseName}.cpp" )
endif ()
if ( NOT ${Antlr4_ParserBaseName} STREQUAL "" )
list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_ParserBaseName}.h" )
list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_ParserBaseName}.cpp" )
endif ()
# process optional arguments ...
if ( ( ARGC GREATER_EQUAL 4 ) AND ARGV3 )
set(Antlr4_BuildListenerOption "-listener")
list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}BaseListener.h" )
list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}BaseListener.cpp" )
list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}Listener.h" )
list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}Listener.cpp" )
list( APPEND Antlr4_GeneratorStatusMessage ", Listener Include- and Sourcefiles" )
else()
set(Antlr4_BuildListenerOption "-no-listener")
endif ()
if ( ( ARGC GREATER_EQUAL 5 ) AND ARGV4 )
set(Antlr4_BuildVisitorOption "-visitor")
list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}BaseVisitor.h" )
list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}BaseVisitor.cpp" )
list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}Visitor.h" )
list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}Visitor.cpp" )
list( APPEND Antlr4_GeneratorStatusMessage ", Visitor Include- and Sourcefiles" )
else()
set(Antlr4_BuildVisitorOption "-no-visitor")
endif ()
if ( (ARGC GREATER_EQUAL 6 ) AND (NOT ${ARGV5} STREQUAL "") )
set(Antlr4_NamespaceOption "-package;${ARGV5}")
list( APPEND Antlr4_GeneratorStatusMessage " in Namespace ${ARGV5}" )
else()
set(Antlr4_NamespaceOption "")
endif ()
if ( (ARGC GREATER_EQUAL 7 ) AND (NOT ${ARGV6} STREQUAL "") )
set(Antlr4_AdditionalDependencies ${ARGV6})
else()
set(Antlr4_AdditionalDependencies "")
endif ()
if ( (ARGC GREATER_EQUAL 8 ) AND (NOT ${ARGV7} STREQUAL "") )
set(Antlr4_LibOption "-lib;${ARGV7}")
list( APPEND Antlr4_GeneratorStatusMessage " using Library ${ARGV7}" )
else()
set(Antlr4_LibOption "")
endif ()
if(NOT Java_FOUND)
message(FATAL_ERROR "Java is required to process grammar or lexer files! - Use 'FIND_PACKAGE(Java COMPONENTS Runtime REQUIRED)'")
endif()
if(NOT EXISTS "${ANTLR4_JAR_LOCATION}")
message(FATAL_ERROR "Unable to find antlr tool. ANTLR4_JAR_LOCATION:${ANTLR4_JAR_LOCATION}")
endif()
# The call to generate the files
add_custom_command(
OUTPUT ${Antlr4_GeneratedTargets}
# Remove target directory
COMMAND
${CMAKE_COMMAND} -E remove_directory ${Antlr4_GeneratedSrcDir}
# Create target directory
COMMAND
${CMAKE_COMMAND} -E make_directory ${Antlr4_GeneratedSrcDir}
COMMAND
# Generate files
"${Java_JAVA_EXECUTABLE}" -jar "${ANTLR4_JAR_LOCATION}" -Werror -Dlanguage=Cpp ${Antlr4_BuildListenerOption} ${Antlr4_BuildVisitorOption} ${Antlr4_LibOption} ${ANTLR4_GENERATED_OPTIONS} -o "${Antlr4_GeneratedSrcDir}" ${Antlr4_NamespaceOption} "${Antlr4_InputFile}"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
MAIN_DEPENDENCY "${Antlr4_InputFile}"
DEPENDS ${Antlr4_AdditionalDependencies}
)
# set output variables in parent scope
set( ANTLR4_INCLUDE_DIR_${Antlr4_ProjectTarget} ${Antlr4_GeneratedSrcDir} PARENT_SCOPE)
set( ANTLR4_SRC_FILES_${Antlr4_ProjectTarget} ${Antlr4_GeneratedTargets} PARENT_SCOPE)
set( ANTLR4_TOKEN_FILES_${Antlr4_ProjectTarget} ${DependentTargets} PARENT_SCOPE)
set( ANTLR4_TOKEN_DIRECTORY_${Antlr4_ProjectTarget} ${Antlr4_GeneratedSrcDir} PARENT_SCOPE)
# export generated cpp files into list
foreach(generated_file ${Antlr4_GeneratedTargets})
if (NOT CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
set_source_files_properties(
${generated_file}
PROPERTIES
COMPILE_FLAGS -Wno-overloaded-virtual
)
endif ()
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
set_source_files_properties(
${generated_file}
PROPERTIES
COMPILE_FLAGS -wd4251
)
endif ()
endforeach(generated_file)
message(STATUS "Antlr4 ${Antlr4_ProjectTarget} - Building " ${Antlr4_GeneratorStatusMessage} )
endfunction()

View File

@ -0,0 +1,13 @@
set(ANTLR_VERSION @ANTLR_VERSION@)
@PACKAGE_INIT@
set_and_check(ANTLR4_INCLUDE_DIR "@PACKAGE_ANTLR4_INCLUDE_DIR@")
set_and_check(ANTLR4_LIB_DIR "@PACKAGE_ANTLR4_LIB_DIR@")
include(CMakeFindDependencyMacro)
find_dependency(Threads)
include(${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake)
check_required_components(antlr)

Binary file not shown.

Binary file not shown.

BIN
docs/VisionFive2.pdf Normal file

Binary file not shown.

26
src/main.cpp Normal file
View File

@ -0,0 +1,26 @@
#include <iostream>
#include "antlr4-runtime.h"
#include "SysYLexer.h"
#include "SysYParser.h"
using namespace antlrSysY;
using namespace antlr4;
int main(int , const char **) {
ANTLRInputStream input(u8"🍴 = 🍐 + \"😎\";(((x * π))) * µ + ∰; a + (x * (y ? 0 : 1) + z);");
SysYLexer lexer(&input);
CommonTokenStream tokens(&lexer);
tokens.fill();
for (auto token : tokens.getTokens()) {
std::cout << token->toString() << std::endl;
}
SysYParser parser(&tokens);
tree::ParseTree* tree = parser.program();
std::cout << tree->toStringTree(&parser) << std::endl << std::endl;
return 0;
}

Binary file not shown.

BIN
tools/antlr4-4.12.0.zip Normal file

Binary file not shown.