From d2d3c1cf67ed72879b3146732f7573db2b57bfcb Mon Sep 17 00:00:00 2001 From: Nathanael Sensfelder Date: Thu, 2 Jul 2020 21:26:21 +0200 Subject: Initial commit. This is re-using an old commit, I will likely have to clean that up. --- src/core/Makefile | 108 ++++++++++ src/core/src/Manifest.txt | 2 + src/core/src/tonkadur/Main.java | 17 ++ src/core/src/tonkadur/parser/Fate.java | 25 +++ src/core/src/tonkadur/parser/LangLexer.g4 | 65 ++++++ src/core/src/tonkadur/parser/LangParser.g4 | 315 +++++++++++++++++++++++++++++ 6 files changed, 532 insertions(+) create mode 100644 src/core/Makefile create mode 100644 src/core/src/Manifest.txt create mode 100644 src/core/src/tonkadur/Main.java create mode 100644 src/core/src/tonkadur/parser/Fate.java create mode 100644 src/core/src/tonkadur/parser/LangLexer.g4 create mode 100644 src/core/src/tonkadur/parser/LangParser.g4 diff --git a/src/core/Makefile b/src/core/Makefile new file mode 100644 index 0000000..178f01b --- /dev/null +++ b/src/core/Makefile @@ -0,0 +1,108 @@ +## Parameters ################################################################## +SRC_DIR ?= ${CURDIR}/src +BIN_DIR ?= ${CURDIR}/bin +LIB_DIR ?= ${CURDIR}/../../lib +TMP_DIR ?= /tmp/tonkadir/ + +TARGET ?= tonkadur_core_lib.jar +STANDALONE ?= tonkadur_core_standalone.jar +INSTALL_DIR ?= ${CURDIR} + +#### Where to get the missing Jar files. +JAR_SOURCE ?= "https://noot-noot.org/jar_dist/" + +#### Binaries +###### JAR binary +JAR ?= jar + +###### JRE binary +JAVA ?= java + +###### JDK binary +JAVAC ?= javac + +###### ANTLR +ANTLR_JAR ?= $(LIB_DIR)/antlr-4.7-complete.jar + +##### Downloader +DOWNLOADER ?= wget + +## Parameters Sanity Check ##################################################### +ifeq ($(strip $(JAVA)),) +$(error No Java executable defined as parameter.) +endif + +ifeq ($(strip $(JAVAC)),) +$(error No Java compiler defined as parameter.) +endif + +ifeq ($(strip $(ANTLR_JAR)),) +$(error No ANTLR_JAR defined as parameter.) +endif + +## Java Config ################################################################# +ifeq ($(strip $(CLASSPATH)),) +CLASSPATH = "$(SRC_DIR):$(BIN_DIR):$(ANTLR_JAR)" +else +CLASSPATH = "$(CLASSPATH):$(SRC_DIR):$(BIN_DIR):$(ANTLR_JAR)" +endif + +MANIFEST ?= $(SRC_DIR)/Manifest.txt + +## Makefile Magic ############################################################## +JAVA_NAMED_FILES = $(shell find $(SRC_DIR) -iname \*.java) +ANTLR_SOURCES = $(shell find $(SRC_DIR) -iname \*.g4) +ANTLR_JAVA_SOURCES = $(ANTLR_SOURCES:.g4=.java) +JAVA_SOURCES = \ + $(filter-out $(ANTLR_JAVA_SOURCES), $(JAVA_NAMED_FILES)) \ + $(ANTLR_JAVA_SOURCES) +CLASSES = $(patsubst $(SRC_DIR)/%.java,$(BIN_DIR)/%.class,$(JAVA_SOURCES)) + +## Makefile Rules ############################################################## +$(STANDALONE): $(TMP_DIR) $(TARGET) $(ANTLR_JAR) + unzip -d $(TMP_DIR) -uo $(TARGET) + unzip -d $(TMP_DIR) -uo $(ANTLR_JAR) + $(JAR) -cvfm $@ $(MANIFEST) -C $(TMP_DIR) . + +ifeq ($(INSTALL_DIR),${CURDIR}) +$(TARGET): $(ANTLR_JAR) $(JAVA_SOURCES) $(CLASSES) $(MANIFEST) + rm -f $(TARGET) $(INSTALL_DIR)/$@ + $(JAR) cf $@ -C $(BIN_DIR) . +else +$(TARGET): $(ANTLR_JAR) $(JAVA_SOURCES) $(CLASSES) $(MANIFEST) + rm -f $(TARGET) $(INSTALL_DIR)/$@ + $(JAR) cf $@ -C $(BIN_DIR) . + cp -f $@ $(INSTALL_DIR)/$@ +endif + +clean: + rm -rf $(filter-out $(ANTLR_SOURCES),$(wildcard $(ANTLR_SOURCES:.g4=*))) + rm -rf $(BIN_DIR)/* + rm -rf $(TARGET) $(STANDALONE) + +$(SRC_DIR)/tonkadur/parser/LangParser.java: $(ANTLR_SOURCES) + +# Pattern rules can be used to generate multiple target in a single action. +LangLexer%java LangParser%java: $(ANTLR_SOURCES) + $(JAVA) -jar $(ANTLR_JAR) -lib $(SRC_DIR)/tonkadur/parser/ $^ + +$(CLASSES): $(BIN_DIR)/%.class: $(SRC_DIR)/%.java $(BIN_DIR) + $(JAVAC) -cp $(CLASSPATH) -d $(BIN_DIR) $< + +%.jar: + $(MAKE) $(LIB_DIR) + echo "Attempting to download missing jar '$@'..." + cd $(LIB_DIR); $(DOWNLOADER) "$(JAR_SOURCE)/$(notdir $@)" + +$(TMP_DIR): + mkdir -p $@ + +$(LIB_DIR): + mkdir -p $@ + +$(BIN_DIR): + mkdir -p $@ + +##### For my private use... +publish: $(TARGET) $(STANDALONE) + scp $^ dreamhost:~/noot-noot/jar_dist/ diff --git a/src/core/src/Manifest.txt b/src/core/src/Manifest.txt new file mode 100644 index 0000000..ef7c812 --- /dev/null +++ b/src/core/src/Manifest.txt @@ -0,0 +1,2 @@ +Main-Class: tonkadur.Main + diff --git a/src/core/src/tonkadur/Main.java b/src/core/src/tonkadur/Main.java new file mode 100644 index 0000000..3d90395 --- /dev/null +++ b/src/core/src/tonkadur/Main.java @@ -0,0 +1,17 @@ +package tonkadur; + +import java.io.IOException; + +import tonkadur.parser.Fate; + +public class Main +{ + /* Utility class */ + private Main () {}; + + public static void main (final String[] args) + throws IOException + { + Fate.parse_file(args[0]); + } +} diff --git a/src/core/src/tonkadur/parser/Fate.java b/src/core/src/tonkadur/parser/Fate.java new file mode 100644 index 0000000..9169975 --- /dev/null +++ b/src/core/src/tonkadur/parser/Fate.java @@ -0,0 +1,25 @@ +package tonkadur.parser; + +import java.io.IOException; + +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CommonTokenStream; + +public class Fate +{ + /* Utility class. */ + private Fate () {} + + public static void parse_file (final String filename) + throws IOException + { + final CommonTokenStream tokens; + final LangLexer lexer; + final LangParser parser; + + lexer = new LangLexer(CharStreams.fromFileName(filename)); + tokens = new CommonTokenStream(lexer); + parser = new LangParser(tokens); + parser.fate_file(); + } +} diff --git a/src/core/src/tonkadur/parser/LangLexer.g4 b/src/core/src/tonkadur/parser/LangLexer.g4 new file mode 100644 index 0000000..9ef92b8 --- /dev/null +++ b/src/core/src/tonkadur/parser/LangLexer.g4 @@ -0,0 +1,65 @@ +lexer grammar LangLexer; + +@header +{ + package tonkadur.parser; +} + + + +fragment SEP: [ \t\r\n]+; + +WS: SEP; + +L_PAREN: WS* '('; +R_PAREN: WS* ')'; + +ADD_KW: L_PAREN 'add' WS*; +ADD_TO_ENUM_TYPE_KW: L_PAREN 'add_to_enum_type' WS*; +ADD_VARIABLE_ATTRIBUTE_KW: L_PAREN 'add_variable_attribute' WS*; +AND_KW: L_PAREN 'and' WS*; +ASSERT_KW: L_PAREN 'assert' WS*; +CLEAR_KW: L_PAREN 'clear' WS*; +COND_KW: L_PAREN 'cond' WS*; +COUNT_KW: L_PAREN 'count' WS*; +DECLARE_ALIAS_TYPE_KW: L_PAREN 'declare_alias_type' WS*; +DECLARE_DICT_TYPE_KW: L_PAREN 'declare_dict_type' WS*; +DECLARE_ENUM_TYPE_KW: L_PAREN 'declare_enum_type' WS*; +DECLARE_EVENT_TYPE_KW: L_PAREN 'declare_event_type' WS*; +DECLARE_VARIABLE_KW: L_PAREN 'declare_variable' WS*; +DEFINE_MACRO_KW: L_PAREN 'define_macro' WS*; +DEFINE_SEQUENCE_KW: L_PAREN 'define_sequence' WS*; +DIVIDE_KW: L_PAREN 'divide' WS*; +ENABLE_TEXT_PARAMETER_KW: L_PAREN 'enable_text_parameter' WS*; +EQUALS_KW: L_PAREN 'equals' WS*; +EVENT_KW: L_PAREN 'event' WS*; +GREATER_EQUAL_THAN_KW: L_PAREN 'greater_equal_than' WS*; +GREATER_THAN_KW: L_PAREN 'greater_than' WS*; +IF_ELSE_KW: L_PAREN 'if_else' WS*; +IF_KW: L_PAREN 'if' WS*; +IMPLIES_KW: L_PAREN 'implies' WS*; +IS_MEMBER_KW: L_PAREN 'is_member' WS*; +LOWER_EQUAL_THAN_KW: L_PAREN 'lower_equal_than' WS*; +LOWER_THAN_KW: L_PAREN 'lower_than' WS*; +MACRO_KW: L_PAREN 'macro' WS*; +MINUS_KW: L_PAREN 'minus' WS*; +NEWLINE_KW: L_PAREN 'newline' WS*; +NOT_KW: L_PAREN 'not' WS*; +ONE_IN_KW: L_PAREN 'one_in' WS*; +OR_KW: L_PAREN 'or' WS*; +PARAMETER_KW: L_PAREN 'parameter' WS*; +PLUS_KW: L_PAREN 'plus' WS*; +POWER_KW: L_PAREN 'power' WS*; +RANDOM_KW: L_PAREN 'random' WS*; +REMOVE_ALL_KW: L_PAREN 'remove_all' WS*; +REMOVE_ONE_KW: L_PAREN 'remove_one' WS*; +REQUIRE_KW: L_PAREN 'require' WS*; +SEQUENCE_KW: L_PAREN 'sequence' WS*; +SET_EXPRESSION_KW: L_PAREN 'set_expression' WS*; +SET_KW: L_PAREN 'set' WS*; +TIMES_KW: L_PAREN 'times' WS*; +VARIABLE_KW: L_PAREN 'variable' WS*; + +WORD: (~([\t\r\n()])|'\\)'|'\\(')+; + +COMMENT: WS* ';' .*? '\n' -> channel(HIDDEN); diff --git a/src/core/src/tonkadur/parser/LangParser.g4 b/src/core/src/tonkadur/parser/LangParser.g4 new file mode 100644 index 0000000..c44acfe --- /dev/null +++ b/src/core/src/tonkadur/parser/LangParser.g4 @@ -0,0 +1,315 @@ +parser grammar LangParser; + +options +{ + tokenVocab = LangLexer; +} + +@header +{ + package tonkadur.parser; +} + +@members +{ + /* of the class */ +} + +/******************************************************************************/ +/******************************************************************************/ +/******************************************************************************/ +fate_file: + (WS* + (first_level_fate_instr|general_fate_instr) + { + } + WS*)* + EOF + { + } +; + +general_fate_sequence: + (WS* general_fate_instr WS*)* + { + } +; + +first_level_fate_instr: + DEFINE_SEQUENCE_KW WORD WS+ general_fate_sequence R_PAREN + { + } + + | DECLARE_VARIABLE_KW range=WORD WS+ type=WORD WS+ name=WORD R_PAREN + { + } + + | ADD_VARIABLE_ATTRIBUTE_KW WORD WS+ WORD R_PAREN + { + } + + | DECLARE_ALIAS_TYPE_KW parent=WORD WS+ name=WORD R_PAREN + { + } + + | DECLARE_DICT_TYPE_KW name=WORD typed_param_list R_PAREN + { + } + + | DECLARE_ENUM_TYPE_KW name=WORD R_PAREN + { + } + + | DECLARE_EVENT_TYPE_KW name=WORD WS+ word_list R_PAREN + { + } + + | ADD_TO_ENUM_TYPE_KW entry=WORD WS+ name=WORD R_PAREN + { + } + + | REQUIRE_KW WORD R_PAREN + { + } + + | DEFINE_MACRO_KW + L_PAREN WS+ typed_param_list R_PAREN + general_fate_sequence + R_PAREN + { + } +; + +general_fate_instr: + L_PAREN general_fate_sequence R_PAREN + { + } + + | CLEAR_KW value_reference R_PAREN + { + } + + | SET_KW value WS+ value_reference R_PAREN + { + } + + | SET_EXPRESSION_KW value WS+ value_reference R_PAREN + { + } + + | EVENT_KW WORD WS+ value_list R_PAREN + { + } + + | MACRO_KW WORD WS+ value_list R_PAREN + { + } + + | SEQUENCE_KW WORD R_PAREN + { + } + + | ENABLE_TEXT_PARAMETER_KW value WS+ sentence R_PAREN + { + } + + | ASSERT_KW value R_PAREN + { + } + + | IF_KW value WS+ general_fate_instr R_PAREN + { + } + + | NEWLINE_KW + { + } + + | sentence + { + } +; + +sentence + @init + { + final StringBuilder string_builder = new StringBuilder(); + } + : + + first_word=WORD + ( + WS next_word=WORD + { + string_builder.append(" "); + string_builder.append(($next_word.text)); + } + )+ + { + string_builder.insert(0, ($first_word.text)); + } +; + +word_list: + WORD? + { + } + + | WORD (WS+ WORD)* + { + } +; + +typed_param_list: + (L_PAREN WORD WS+ WORD R_PAREN)* + { + } +; +/******************************************************************************/ +/**** VALUES ******************************************************************/ +/******************************************************************************/ +boolean_expression: + AND_KW value_list R_PAREN + { + } + + | OR_KW value_list R_PAREN + { + } + + | ONE_IN_KW value_list R_PAREN + { + } + + | NOT_KW value R_PAREN + { + } + + | IMPLIES_KW value WS+ value R_PAREN + { + } + + | LOWER_THAN_KW value WS+ value R_PAREN + { + } + + | LOWER_EQUAL_THAN_KW value WS+ value R_PAREN + { + } + + | EQUALS_KW value WS+ value R_PAREN + { + } + + | GREATER_EQUAL_THAN_KW value WS+ value R_PAREN + { + } + + | GREATER_THAN_KW value WS+ value R_PAREN + { + } + + | IS_MEMBER_KW value WS+ value_reference R_PAREN + { + } +; + +math_expression: + PLUS_KW value_list R_PAREN + { + } + + | MINUS_KW value_list R_PAREN + { + } + + | TIMES_KW value_list R_PAREN + { + } + + | DIVIDE_KW value WS+ value R_PAREN + { + } + + | POWER_KW value WS+ value R_PAREN + { + } + + | RANDOM_KW value WS+ value R_PAREN + { + } + + | COUNT_KW value WS+ value_reference R_PAREN + { + } +; + +bag_expression: + | ADD_KW value WS+ value_reference R_PAREN + { + } + + | REMOVE_ONE_KW value WS+ value_reference R_PAREN + { + } + + | REMOVE_ALL_KW value WS+ value_reference R_PAREN + { + } +; + +value: + WORD + { + } + + | L_PAREN WS+ sentence WS+ R_PAREN + { + } + + | IF_ELSE_KW value WS+ value WS+ value R_PAREN + { + } + + | COND_KW value_cond_list R_PAREN + { + } + + | boolean_expression + { + } + + | math_expression + { + } + + | value_reference + { + } + + | SET_KW value WS+ value_reference R_PAREN + { + } +; + +value_reference: + VARIABLE_KW WORD R_PAREN + { + } + + | PARAMETER_KW WORD R_PAREN + { + } +; + +value_cond_list: + (L_PAREN value WS value R_PAREN)+ + { + } +; + +value_list: + value* + { + } +; -- cgit v1.2.3-70-g09d2