| summaryrefslogtreecommitdiff |
diff options
| author | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2020-07-05 17:45:23 +0200 |
|---|---|---|
| committer | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2020-07-05 17:45:23 +0200 |
| commit | 8a78ec95b126ef653a2990161e541f97eab0ed88 (patch) | |
| tree | ed0b2e48c048718c749744333f663c276da5f3d9 | |
| parent | 4dffb5be5c2b2e8872fb74a5e06b9cd861a70c22 (diff) | |
Starting to put code logic in Lexer...
21 files changed, 653 insertions, 150 deletions
diff --git a/src/core/src/tonkadur/Main.java b/src/core/src/tonkadur/Main.java index c8f8f1b..382dab6 100644 --- a/src/core/src/tonkadur/Main.java +++ b/src/core/src/tonkadur/Main.java @@ -2,6 +2,8 @@ package tonkadur; import java.io.IOException; +import tonkadur.parser.Context; + import tonkadur.fate.v1.lang.World; import tonkadur.fate.v1.Utils; @@ -15,9 +17,14 @@ public class Main throws IOException { final World world; + final Context context; world = new World(); + context = new Context(args[0]); + + Utils.add_file_content(args[0], context, world); - Utils.add_file_content(args[0], world); + System.out.println("Parsing completed."); + System.out.println(world.toString()); } } diff --git a/src/core/src/tonkadur/fate/v1/Utils.java b/src/core/src/tonkadur/fate/v1/Utils.java index 562adee..1049e0d 100644 --- a/src/core/src/tonkadur/fate/v1/Utils.java +++ b/src/core/src/tonkadur/fate/v1/Utils.java @@ -5,6 +5,8 @@ import java.io.IOException; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; +import tonkadur.parser.Context; + import tonkadur.fate.v1.parser.FateLexer; import tonkadur.fate.v1.parser.FateParser; @@ -18,6 +20,7 @@ public class Utils public static void add_file_content ( final String filename, + final Context context, final World world ) throws IOException @@ -30,6 +33,13 @@ public class Utils tokens = new CommonTokenStream(lexer); parser = new FateParser(tokens); - parser.fate_file(world); + parser.fate_file(context, world); + + world.add_loaded_file(filename); + + if (parser.getNumberOfSyntaxErrors() > 0) + { + throw new IOException("There were syntaxic errors in" + filename); + } } } diff --git a/src/core/src/tonkadur/fate/v1/error/ConflictingDeclarationException.java b/src/core/src/tonkadur/fate/v1/error/ConflictingDeclarationException.java index 34e1a98..fdd93b8 100644 --- a/src/core/src/tonkadur/fate/v1/error/ConflictingDeclarationException.java +++ b/src/core/src/tonkadur/fate/v1/error/ConflictingDeclarationException.java @@ -40,9 +40,12 @@ public class ConflictingDeclarationException extends ParsingError { final StringBuilder sb = new StringBuilder(); - sb.append(origin.get_context().toString()); + sb.append(origin.toString()); + sb.append(" "); sb.append(error_category.toString()); - sb.append(" Declaration for "); + sb.append(System.lineSeparator()); + + sb.append("Declaration for "); sb.append(original_declaration.get_type_name()); sb.append(" '"); sb.append(original_declaration.get_name()); diff --git a/src/core/src/tonkadur/fate/v1/error/ConflictingTypeException.java b/src/core/src/tonkadur/fate/v1/error/ConflictingTypeException.java index 3cf287e..f084ea9 100644 --- a/src/core/src/tonkadur/fate/v1/error/ConflictingTypeException.java +++ b/src/core/src/tonkadur/fate/v1/error/ConflictingTypeException.java @@ -41,9 +41,12 @@ public class ConflictingTypeException extends ParsingError { final StringBuilder sb = new StringBuilder(); - sb.append(origin.get_context().toString()); + sb.append(origin.toString()); + sb.append(" "); sb.append(error_category.toString()); - sb.append(" Resulting type '"); + sb.append(System.lineSeparator()); + + sb.append("Resulting type '"); sb.append(given_type.get_name()); sb.append("' "); sb.append(" conflicts with the expected one ('"); diff --git a/src/core/src/tonkadur/fate/v1/error/DuplicateDeclarationException.java b/src/core/src/tonkadur/fate/v1/error/DuplicateDeclarationException.java index eb42aba..5e0b5d0 100644 --- a/src/core/src/tonkadur/fate/v1/error/DuplicateDeclarationException.java +++ b/src/core/src/tonkadur/fate/v1/error/DuplicateDeclarationException.java @@ -32,9 +32,12 @@ public class DuplicateDeclarationException extends ParsingError { final StringBuilder sb = new StringBuilder(); - sb.append(origin.get_context().toString()); + sb.append(origin.toString()); + sb.append(" "); sb.append(error_category.toString()); - sb.append(" Declaration for "); + sb.append(System.lineSeparator()); + + sb.append("Declaration for "); sb.append(original_declaration.get_type_name()); sb.append(" '"); sb.append(original_declaration.get_name()); diff --git a/src/core/src/tonkadur/fate/v1/error/IncomparableDeclarationException.java b/src/core/src/tonkadur/fate/v1/error/IncomparableDeclarationException.java index c5dfc94..d4968ce 100644 --- a/src/core/src/tonkadur/fate/v1/error/IncomparableDeclarationException.java +++ b/src/core/src/tonkadur/fate/v1/error/IncomparableDeclarationException.java @@ -40,9 +40,12 @@ public class IncomparableDeclarationException extends ParsingError { final StringBuilder sb = new StringBuilder(); - sb.append(origin.get_context().toString()); + sb.append(origin.toString()); + sb.append(" "); sb.append(error_category.toString()); - sb.append(" Declaration for "); + sb.append(System.lineSeparator()); + + sb.append("Declaration for "); sb.append(original_declaration.get_type_name()); sb.append(" '"); sb.append(original_declaration.get_name()); diff --git a/src/core/src/tonkadur/fate/v1/error/IncomparableTypeException.java b/src/core/src/tonkadur/fate/v1/error/IncomparableTypeException.java index 19ae9d6..b3fa548 100644 --- a/src/core/src/tonkadur/fate/v1/error/IncomparableTypeException.java +++ b/src/core/src/tonkadur/fate/v1/error/IncomparableTypeException.java @@ -41,9 +41,12 @@ public class IncomparableTypeException extends ParsingError { final StringBuilder sb = new StringBuilder(); - sb.append(origin.get_context().toString()); + sb.append(origin.toString()); + sb.append(" "); sb.append(error_category.toString()); - sb.append(" Resulting type '"); + sb.append(System.lineSeparator()); + + sb.append("Resulting type '"); sb.append(given_type.toString()); sb.append("' "); sb.append(" is incomparable with the expected one ('"); diff --git a/src/core/src/tonkadur/fate/v1/error/IncompatibleDeclarationException.java b/src/core/src/tonkadur/fate/v1/error/IncompatibleDeclarationException.java index ce8792a..8e46283 100644 --- a/src/core/src/tonkadur/fate/v1/error/IncompatibleDeclarationException.java +++ b/src/core/src/tonkadur/fate/v1/error/IncompatibleDeclarationException.java @@ -61,9 +61,12 @@ public class IncompatibleDeclarationException extends ParsingError { final StringBuilder sb = new StringBuilder(); - sb.append(origin.get_context().toString()); + sb.append(origin.toString()); + sb.append(" "); sb.append(error_category.toString()); - sb.append(" Declaration for "); + sb.append(System.lineSeparator()); + + sb.append("Declaration for "); sb.append(original_declaration.get_type_name()); sb.append(" '"); sb.append(original_declaration.get_name()); diff --git a/src/core/src/tonkadur/fate/v1/error/IncompatibleTypeException.java b/src/core/src/tonkadur/fate/v1/error/IncompatibleTypeException.java index da05cb9..b79f293 100644 --- a/src/core/src/tonkadur/fate/v1/error/IncompatibleTypeException.java +++ b/src/core/src/tonkadur/fate/v1/error/IncompatibleTypeException.java @@ -41,9 +41,12 @@ public class IncompatibleTypeException extends ParsingError { final StringBuilder sb = new StringBuilder(); - sb.append(origin.get_context().toString()); + sb.append(origin.toString()); + sb.append(" "); sb.append(error_category.toString()); - sb.append(" Resulting type '"); + sb.append(System.lineSeparator()); + + sb.append("Resulting type '"); sb.append(given_type.toString()); sb.append("' "); sb.append(" is incompatible with the expected one ('"); diff --git a/src/core/src/tonkadur/fate/v1/error/InvalidArityException.java b/src/core/src/tonkadur/fate/v1/error/InvalidArityException.java index 578ce60..f4f8205 100644 --- a/src/core/src/tonkadur/fate/v1/error/InvalidArityException.java +++ b/src/core/src/tonkadur/fate/v1/error/InvalidArityException.java @@ -10,7 +10,8 @@ public class InvalidArityException extends ParsingError /***************************************************************************/ /**** MEMBERS **************************************************************/ /***************************************************************************/ - protected final int arity; + protected final int min_arity; + protected final int max_arity; protected final int arguments_count; /***************************************************************************/ @@ -20,7 +21,8 @@ public class InvalidArityException extends ParsingError ( final Origin call_origin, final int arguments_count, - final int arity + final int min_arity, + final int max_arity ) { super @@ -31,7 +33,8 @@ public class InvalidArityException extends ParsingError ); this.arguments_count = arguments_count; - this.arity = arity; + this.min_arity = min_arity; + this.max_arity = max_arity; } @Override @@ -39,10 +42,20 @@ public class InvalidArityException extends ParsingError { final StringBuilder sb = new StringBuilder(); - sb.append(origin.get_context().toString()); + sb.append(origin.toString()); + sb.append(" "); sb.append(error_category.toString()); - sb.append(" This supports a maximum or a minimum of "); - sb.append(arity); + sb.append(System.lineSeparator()); + + sb.append("This supports a minimum of "); + sb.append(min_arity); + + if (max_arity > 0) + { + sb.append(" and a maximum of "); + sb.append(max_arity); + } + sb.append(" parameter(s), but was given "); sb.append(arguments_count); sb.append(" of them."); diff --git a/src/core/src/tonkadur/fate/v1/error/InvalidTypeException.java b/src/core/src/tonkadur/fate/v1/error/InvalidTypeException.java index 6a62edd..eb9d158 100644 --- a/src/core/src/tonkadur/fate/v1/error/InvalidTypeException.java +++ b/src/core/src/tonkadur/fate/v1/error/InvalidTypeException.java @@ -43,9 +43,12 @@ public class InvalidTypeException extends ParsingError { final StringBuilder sb = new StringBuilder(); - sb.append(origin.get_context().toString()); + sb.append(origin.toString()); + sb.append(" "); sb.append(error_category.toString()); - sb.append(" Type '"); + sb.append(System.lineSeparator()); + + sb.append("Type '"); sb.append(given_type.toString()); sb.append("' "); sb.append(" is not useable here. The following base types are allowed:"); @@ -54,7 +57,7 @@ public class InvalidTypeException extends ParsingError { sb.append(System.lineSeparator()); sb.append("- "); - sb.append(allowed_types.toString()); + sb.append(allowed_type.toString()); } return sb.toString(); diff --git a/src/core/src/tonkadur/fate/v1/error/MissingDeclarationException.java b/src/core/src/tonkadur/fate/v1/error/MissingDeclarationException.java index c4cb08f..57c2932 100644 --- a/src/core/src/tonkadur/fate/v1/error/MissingDeclarationException.java +++ b/src/core/src/tonkadur/fate/v1/error/MissingDeclarationException.java @@ -33,9 +33,12 @@ public class MissingDeclarationException extends ParsingError { final StringBuilder sb = new StringBuilder(); - sb.append(origin.get_context().toString()); + sb.append(origin.toString()); + sb.append(" "); sb.append(error_category.toString()); - sb.append(" Unknown "); + sb.append(System.lineSeparator()); + + sb.append("Unknown "); sb.append(type_name); sb.append(" '"); sb.append(name); diff --git a/src/core/src/tonkadur/fate/v1/error/UnknownDictionaryFieldException.java b/src/core/src/tonkadur/fate/v1/error/UnknownDictionaryFieldException.java index a624fb8..dd3e67d 100644 --- a/src/core/src/tonkadur/fate/v1/error/UnknownDictionaryFieldException.java +++ b/src/core/src/tonkadur/fate/v1/error/UnknownDictionaryFieldException.java @@ -38,9 +38,12 @@ public class UnknownDictionaryFieldException extends ParsingError { final StringBuilder sb = new StringBuilder(); - sb.append(origin.get_context().toString()); + sb.append(origin.toString()); + sb.append(" "); sb.append(error_category.toString()); - sb.append(" Unknown field '"); + sb.append(System.lineSeparator()); + + sb.append("Unknown field '"); sb.append(field_name); sb.append("' for dictionary type '"); sb.append(dict.get_name()); diff --git a/src/core/src/tonkadur/fate/v1/lang/Constant.java b/src/core/src/tonkadur/fate/v1/lang/Constant.java index 7123b26..9c13b1f 100644 --- a/src/core/src/tonkadur/fate/v1/lang/Constant.java +++ b/src/core/src/tonkadur/fate/v1/lang/Constant.java @@ -31,7 +31,16 @@ public class Constant extends ValueNode /**** PUBLIC ***************************************************************/ /***************************************************************************/ /**** Constructors *********************************************************/ - public Constant build (final Origin origin, final String as_string) + public static Constant build_boolean + ( + final Origin origin, + final boolean value + ) + { + return new Constant(origin, Type.BOOLEAN, value ? "true" : "false"); + } + + public static Constant build (final Origin origin, final String as_string) { try { @@ -55,17 +64,6 @@ public class Constant extends ValueNode /* That's fine, we're just testing... */ } - try - { - Boolean.valueOf(as_string); - - return new Constant(origin, Type.BOOLEAN, as_string); - } - catch (final NumberFormatException nfe) - { - /* That's fine, we're just testing... */ - } - return new Constant(origin, Type.STRING, as_string); } diff --git a/src/core/src/tonkadur/fate/v1/lang/Operation.java b/src/core/src/tonkadur/fate/v1/lang/Operation.java index b193f5b..4b05a68 100644 --- a/src/core/src/tonkadur/fate/v1/lang/Operation.java +++ b/src/core/src/tonkadur/fate/v1/lang/Operation.java @@ -34,7 +34,7 @@ public class Operation extends ValueNode this.operands = operands; } - public Operation build + public static Operation build ( final Origin origin, final Operator operator, @@ -48,21 +48,35 @@ public class Operation extends ValueNode InvalidTypeException { final Collection<Type> allowed_base_types; - final int operator_arity; + final int operator_max_arity; + final int operator_min_arity; + final int operands_size; Type computed_type, previous_computed_type; allowed_base_types = operator.get_allowed_base_types(); - operator_arity = operator.get_arity(); + operator_max_arity = operator.get_maximum_arity(); + operator_min_arity = operator.get_minimum_arity(); + operands_size = operands.size(); if ( - (operator_arity != 0) - && (operator_arity < operands.size()) + (operands_size < operator_min_arity) + || + ( + (operator_max_arity != 0) + && (operator_max_arity < operands_size) + ) ) { ErrorManager.handle ( - new InvalidArityException(origin, operands.size(), operator_arity) + new InvalidArityException + ( + origin, + operands_size, + operator_min_arity, + operator_max_arity + ) ); } diff --git a/src/core/src/tonkadur/fate/v1/lang/Operator.java b/src/core/src/tonkadur/fate/v1/lang/Operator.java index 9e2e522..84681d7 100644 --- a/src/core/src/tonkadur/fate/v1/lang/Operator.java +++ b/src/core/src/tonkadur/fate/v1/lang/Operator.java @@ -5,38 +5,44 @@ import java.util.Set; public enum Operator { - PLUS("+", 0, Type.NUMBER_TYPES, null), - MINUS("-", 0, Type.NUMBER_TYPES, null), - TIMES("*", 0, Type.NUMBER_TYPES, null), - DIVIDED("/", 0, Type.NUMBER_TYPES, null), - POWER("^", 2, Type.NUMBER_TYPES, null), - RANDOM("rand", 2, Collections.singleton(Type.INT), null), + PLUS("+", 2, 0, Type.NUMBER_TYPES, null), + MINUS("-", 2, 0, Type.NUMBER_TYPES, null), + TIMES("*", 2, 0, Type.NUMBER_TYPES, null), + DIVIDE("/", 2, 2, Type.NUMBER_TYPES, null), + POWER("^", 2, 2, Type.NUMBER_TYPES, null), + RANDOM("rand", 2, 2, Collections.singleton(Type.INT), null), - AND("and", 0, Collections.singleton(Type.BOOLEAN), null), - OR("or", 0, Collections.singleton(Type.BOOLEAN), null), - NOT("not", 1, Collections.singleton(Type.BOOLEAN), null), - IMPLIES("implies", 1, Collections.singleton(Type.BOOLEAN), null), + AND("and", 2, 0, Collections.singleton(Type.BOOLEAN), null), + OR("or", 2, 0, Collections.singleton(Type.BOOLEAN), null), + NOT("not", 1, 1, Collections.singleton(Type.BOOLEAN), null), + IMPLIES("implies", 2, 2, Collections.singleton(Type.BOOLEAN), null), + ONE_IN("one_in", 1, 0, Collections.singleton(Type.BOOLEAN), null), - LOWER_THAN("<", 2, Type.NUMBER_TYPES, Type.BOOLEAN), - LOWER_EQUAL_THAN("=<", 2, Type.NUMBER_TYPES, Type.BOOLEAN), - GREATER_EQUAL_THAN(">=", 2, Type.NUMBER_TYPES, Type.BOOLEAN), - GREATER_THAN(">", 2, Type.NUMBER_TYPES, Type.BOOLEAN); + EQUALS("equals", 2, 0, Type.COLLECTION_COMPATIBLE_TYPES, Type.BOOLEAN), + + LOWER_THAN("<", 2, 2, Type.NUMBER_TYPES, Type.BOOLEAN), + LOWER_EQUAL_THAN("=<", 2, 2, Type.NUMBER_TYPES, Type.BOOLEAN), + GREATER_EQUAL_THAN(">=", 2, 2, Type.NUMBER_TYPES, Type.BOOLEAN), + GREATER_THAN(">", 2, 2, Type.NUMBER_TYPES, Type.BOOLEAN); final private String name; - final private int arity; + final private int min_arity; + final private int max_arity; final private Set<Type> valid_input_types; final private Type output_type_transform; private Operator ( final String name, - final int arity, + final int min_arity, + final int max_arity, final Set<Type> valid_input_types, final Type output_type_transform ) { this.name = name; - this.arity = arity; + this.min_arity = min_arity; + this.max_arity = max_arity; this.valid_input_types = valid_input_types; this.output_type_transform = output_type_transform; @@ -47,9 +53,14 @@ public enum Operator return valid_input_types; } - public int get_arity () + public int get_minimum_arity () + { + return min_arity; + } + + public int get_maximum_arity () { - return arity; + return max_arity; } public Type transform_type (final Type in) diff --git a/src/core/src/tonkadur/fate/v1/lang/World.java b/src/core/src/tonkadur/fate/v1/lang/World.java index 5db6d16..43feb5f 100644 --- a/src/core/src/tonkadur/fate/v1/lang/World.java +++ b/src/core/src/tonkadur/fate/v1/lang/World.java @@ -72,6 +72,41 @@ public class World } /**** Misc. ****************************************************************/ + @Override + public String toString () + { + final StringBuilder sb = new StringBuilder(); + + sb.append("(World"); + sb.append(System.lineSeparator()); + sb.append(System.lineSeparator()); + sb.append("Loaded files: "); + sb.append(System.lineSeparator()); + + for (final String filename: loaded_files) + { + sb.append("- "); + sb.append(filename); + sb.append(System.lineSeparator()); + } + + sb.append(System.lineSeparator()); + sb.append("Events: "); + sb.append(System.lineSeparator()); + sb.append(event_collection.toString()); + sb.append(System.lineSeparator()); + sb.append(System.lineSeparator()); + + sb.append("Types: "); + sb.append(System.lineSeparator()); + sb.append(type_collection.toString()); + sb.append(System.lineSeparator()); + sb.append(System.lineSeparator()); + + sb.append(")"); + + return sb.toString(); + } /***************************************************************************/ /**** PROTECTED ************************************************************/ diff --git a/src/core/src/tonkadur/fate/v1/lang/meta/DeclarationCollection.java b/src/core/src/tonkadur/fate/v1/lang/meta/DeclarationCollection.java index 04bbfa9..81767e9 100644 --- a/src/core/src/tonkadur/fate/v1/lang/meta/DeclarationCollection.java +++ b/src/core/src/tonkadur/fate/v1/lang/meta/DeclarationCollection.java @@ -80,6 +80,27 @@ public class DeclarationCollection <Declared extends DeclaredEntity> return result; } + /**** Misc. ****************************************************************/ + public String toString () + { + final StringBuilder sb = new StringBuilder(); + + sb.append("Default Value: "); + sb.append(value_on_missing.toString()); + sb.append(System.lineSeparator()); + + for (final Map.Entry<String, Declared> entry: collection.entrySet()) + { + sb.append("- "); + sb.append(entry.getKey()); + sb.append(": "); + sb.append(entry.getValue().toString()); + sb.append(System.lineSeparator()); + } + + return sb.toString(); + } + /***************************************************************************/ /**** PROTECTED ************************************************************/ /***************************************************************************/ diff --git a/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 b/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 index 3671a4f..6f03d0c 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 @@ -15,54 +15,56 @@ 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*; +AND_KW: L_PAREN ('and'|'/\\') WS*; ASSERT_KW: L_PAREN 'assert' WS*; +CAST_KW: L_PAREN 'cast' 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_ALIAS_TYPE_KW: L_PAREN 'declare_subtype' 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_TEXT_EFFECT: L_PAREN 'declare_text_effect' WS*; +DECLARE_TEXT_EFFECT_KW: L_PAREN 'declare_text_effect' 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*; +DIVIDE_KW: L_PAREN ('divide'|'/') WS*; ENABLE_TEXT_PARAMETER_KW: L_PAREN 'enable_text_parameter' WS*; -EQUALS_KW: L_PAREN 'equals' WS*; +EQUALS_KW: L_PAREN ('equals'|'='|'==') WS*; EVENT_KW: L_PAREN 'event' WS*; +FALSE_KW: L_PAREN 'false)'; FATE_VERSION_KW: L_PAREN 'fate_version' WS*; -GREATER_EQUAL_THAN_KW: L_PAREN 'greater_equal_than' WS*; -GREATER_THAN_KW: L_PAREN 'greater_than' 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*; +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*; +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*; +MINUS_KW: L_PAREN ('minus'|'-') WS*; NEWLINE_KW: L_PAREN 'newline' WS*; -NOT_KW: L_PAREN 'not' WS*; +NOT_KW: L_PAREN ('not'|'~'|'!') WS*; ONE_IN_KW: L_PAREN 'one_in' WS*; -OR_KW: L_PAREN 'or' 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*; -DECLARE_TEXT_EFFECT_KW: L_PAREN 'declare_text_effect' WS*; PLAYER_CHOICE_KW: L_PAREN 'player_choice' WS*; -CAST_KW: L_PAREN 'cast' WS*; +PLUS_KW: L_PAREN ('plus'|'+') WS*; +POWER_KW: L_PAREN ('power'|'^'|'**') WS*; +RANDOM_KW: L_PAREN ('random'|'rand') 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*; +TIMES_KW: L_PAREN ('times'|'*') WS*; +TRUE_KW: L_PAREN 'true)'; VARIABLE_KW: L_PAREN 'variable' WS*; -WORD: (~([\t\r\n()])|'\\)'|'\\(')+; +WORD: (~([ \t\r\n()])|'\\)'|'\\(')+; COMMENT: WS* ';' .*? '\n' -> channel(HIDDEN); diff --git a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 index 273722f..ccc46db 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 @@ -9,19 +9,32 @@ options { package tonkadur.fate.v1.parser; - import tonkadur.fate.v1.lang.World; + import tonkadur.error.Error; + + import tonkadur.parser.Context; + import tonkadur.parser.Origin; + + import tonkadur.fate.v1.lang.*; + import tonkadur.fate.v1.lang.meta.*; } @members { - /* of the class */ + Context CONTEXT; + World WORLD; } /******************************************************************************/ /******************************************************************************/ /******************************************************************************/ -fate_file [World world]: - WS* FATE_VERSION_KW WORD L_PAREN WS* +fate_file [Context context, World world] + @init + { + CONTEXT = context; + WORLD = world; + } + : + WS* FATE_VERSION_KW WORD R_PAREN WS* ( (first_level_fate_instr|general_fate_instr) { @@ -40,24 +53,94 @@ general_fate_sequence: ; first_level_fate_instr: - DEFINE_SEQUENCE_KW WORD WS+ general_fate_sequence R_PAREN + DEFINE_SEQUENCE_KW WORD WS+ first_node=general_fate_sequence R_PAREN + { + /* + world.sequences().add + ( + CONTEXT.get_origin_at + ( + ($DEFINE_SEQUENCE_KW.getLine()), + ($DEFINE_SEQUENCE_KW.getCharPositionInLine()) + ), + ($WORD.text), + //(first_node.result) + ); + */ + } + + | DECLARE_VARIABLE_KW scope=WORD WS+ type=WORD WS+ name=WORD R_PAREN + { + /* + final Origin start_origin, scope_origin, type_origin; + final VariableScope variable_scope; + final Type variable_type; + final Variable new_variable; + + start_origin = + CONTEXT.get_origin_at + ( + ($DECLARE_VARIABLE_KW.getLine()), + ($DECLARE_VARIABLE_KW.getCharPositionInLine()) + ); + + scope_origin = + CONTEXT.get_origin_at + ( + ($scope.getLine()), + ($scope.getCharPositionInLine()) + ); + + type_origin = + CONTEXT.get_origin_at + ( + ($type.getLine()), + ($type.getCharPositionInLine()) + ); + + variable_scope = VariableScope.value_of(scope_origin, ($scope.text)); + variable_type = WORLD.types().get(($type.text)); + new_variable = + new Variable + ( + start_origin, + variable_scope, + variable_type, + ($name.text) + ); + + WORLD.variables().add(new_variable); + */ + } + + | DECLARE_TEXT_EFFECT_KW params=word_list name=WORD R_PAREN { } - | DECLARE_VARIABLE_KW range=WORD WS+ type=WORD WS+ name=WORD R_PAREN + | DECLARE_ALIAS_TYPE_KW parent=WORD WS+ name=WORD R_PAREN { - } + final Origin start_origin, parent_origin; + final Type parent_type; + final Type new_type; - | DECLARE_TEXT_EFFECT_KW range=WORD R_PAREN - { - } + start_origin = + CONTEXT.get_origin_at + ( + ($DECLARE_ALIAS_TYPE_KW.getLine()), + ($DECLARE_ALIAS_TYPE_KW.getCharPositionInLine()) + ); - | ADD_VARIABLE_ATTRIBUTE_KW WORD WS+ WORD R_PAREN - { - } + parent_origin = + CONTEXT.get_origin_at + ( + ($parent.getLine()), + ($parent.getCharPositionInLine()) + ); - | DECLARE_ALIAS_TYPE_KW parent=WORD WS+ name=WORD R_PAREN - { + parent_type = WORLD.types().get(parent_origin, ($parent.text)); + new_type = new Type(start_origin, parent_type, ($name.text)); + + WORLD.types().add(new_type); } | DECLARE_DICT_TYPE_KW name=WORD typed_param_list R_PAREN @@ -87,9 +170,13 @@ first_level_fate_instr: { } ; +catch [final Throwable e] +{ + throw new ParseCancellationException(e); +} general_fate_instr: - L_PAREN general_fate_sequence R_PAREN + L_PAREN WS+ general_fate_sequence R_PAREN { } @@ -228,81 +315,299 @@ typed_param_list: /******************************************************************************/ /**** VALUES ******************************************************************/ /******************************************************************************/ -boolean_expression: - AND_KW value_list R_PAREN - { +boolean_expression +returns [ValueNode result]: + TRUE_KW + { + $result = + Constant.build_boolean + ( + CONTEXT.get_origin_at + ( + ($TRUE_KW.getLine()), + ($TRUE_KW.getCharPositionInLine()) + ), + true + ); + } + + | FALSE_KW + { + $result = + Constant.build_boolean + ( + CONTEXT.get_origin_at + ( + ($FALSE_KW.getLine()), + ($FALSE_KW.getCharPositionInLine()) + ), + false + ); + } + + | AND_KW value_list R_PAREN + { + $result = + Operation.build + ( + CONTEXT.get_origin_at + ( + ($AND_KW.getLine()), + ($AND_KW.getCharPositionInLine()) + ), + Operator.AND, + ($value_list.result) + ); } | OR_KW value_list R_PAREN { + $result = + Operation.build + ( + CONTEXT.get_origin_at + ( + ($OR_KW.getLine()), + ($OR_KW.getCharPositionInLine()) + ), + Operator.OR, + ($value_list.result) + ); } | 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 - { + $result = + Operation.build + ( + CONTEXT.get_origin_at + ( + ($ONE_IN_KW.getLine()), + ($ONE_IN_KW.getCharPositionInLine()) + ), + Operator.ONE_IN, + ($value_list.result) + ); + } + + | NOT_KW value_list R_PAREN + { + $result = + Operation.build + ( + CONTEXT.get_origin_at + ( + ($NOT_KW.getLine()), + ($NOT_KW.getCharPositionInLine()) + ), + Operator.NOT, + ($value_list.result) + ); + } + + | IMPLIES_KW value_list R_PAREN + { + $result = + Operation.build + ( + CONTEXT.get_origin_at + ( + ($IMPLIES_KW.getLine()), + ($IMPLIES_KW.getCharPositionInLine()) + ), + Operator.IMPLIES, + ($value_list.result) + ); + } + + | LOWER_THAN_KW value_list R_PAREN + { + $result = + Operation.build + ( + CONTEXT.get_origin_at + ( + ($LOWER_THAN_KW.getLine()), + ($LOWER_THAN_KW.getCharPositionInLine()) + ), + Operator.LOWER_THAN, + ($value_list.result) + ); + } + + | LOWER_EQUAL_THAN_KW value_list R_PAREN + { + $result = + Operation.build + ( + CONTEXT.get_origin_at + ( + ($LOWER_EQUAL_THAN_KW.getLine()), + ($LOWER_EQUAL_THAN_KW.getCharPositionInLine()) + ), + Operator.LOWER_EQUAL_THAN, + ($value_list.result) + ); + } + + | EQUALS_KW value_list R_PAREN + { + $result = + Operation.build + ( + CONTEXT.get_origin_at + ( + ($EQUALS_KW.getLine()), + ($EQUALS_KW.getCharPositionInLine()) + ), + Operator.EQUALS, + ($value_list.result) + ); + } + + | GREATER_EQUAL_THAN_KW value_list R_PAREN + { + $result = + Operation.build + ( + CONTEXT.get_origin_at + ( + ($GREATER_EQUAL_THAN_KW.getLine()), + ($GREATER_EQUAL_THAN_KW.getCharPositionInLine()) + ), + Operator.GREATER_EQUAL_THAN, + ($value_list.result) + ); + } + + | GREATER_THAN_KW value_list R_PAREN + { + $result = + Operation.build + ( + CONTEXT.get_origin_at + ( + ($GREATER_THAN_KW.getLine()), + ($GREATER_THAN_KW.getCharPositionInLine()) + ), + Operator.GREATER_THAN, + ($value_list.result) + ); } | IS_MEMBER_KW value WS+ value_reference R_PAREN { + /* TODO */ + $result = null; } ; +catch [final Throwable e] +{ + throw new ParseCancellationException(e); +} -math_expression: +math_expression +returns [ValueNode result]: PLUS_KW value_list R_PAREN { + $result = + Operation.build + ( + CONTEXT.get_origin_at + ( + ($PLUS_KW.getLine()), + ($PLUS_KW.getCharPositionInLine()) + ), + Operator.PLUS, + ($value_list.result) + ); } | MINUS_KW value_list R_PAREN { + $result = + Operation.build + ( + CONTEXT.get_origin_at + ( + ($MINUS_KW.getLine()), + ($MINUS_KW.getCharPositionInLine()) + ), + Operator.MINUS, + ($value_list.result) + ); } | 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 - { + $result = + Operation.build + ( + CONTEXT.get_origin_at + ( + ($TIMES_KW.getLine()), + ($TIMES_KW.getCharPositionInLine()) + ), + Operator.TIMES, + ($value_list.result) + ); + } + + | DIVIDE_KW value_list R_PAREN + { + $result = + Operation.build + ( + CONTEXT.get_origin_at + ( + ($DIVIDE_KW.getLine()), + ($DIVIDE_KW.getCharPositionInLine()) + ), + Operator.DIVIDE, + ($value_list.result) + ); + } + + | POWER_KW value_list R_PAREN + { + $result = + Operation.build + ( + CONTEXT.get_origin_at + ( + ($POWER_KW.getLine()), + ($POWER_KW.getCharPositionInLine()) + ), + Operator.POWER, + ($value_list.result) + ); + } + + | RANDOM_KW value_list R_PAREN + { + $result = + Operation.build + ( + CONTEXT.get_origin_at + ( + ($RANDOM_KW.getLine()), + ($RANDOM_KW.getCharPositionInLine()) + ), + Operator.RANDOM, + ($value_list.result) + ); } | COUNT_KW value WS+ value_reference R_PAREN { + /* TODO */ + $result= null; } ; +catch [final Throwable e] +{ + throw new ParseCancellationException(e); +} bag_expression: | ADD_KW value WS+ value_reference R_PAREN @@ -318,47 +623,76 @@ bag_expression: } ; -value: +value +returns [ValueNode result] +: WORD { + $result = + Constant.build + ( + CONTEXT.get_origin_at + ( + ($WORD.getLine()), + ($WORD.getCharPositionInLine()) + ), + ($WORD.text) + ); } - | L_PAREN WS* sentence R_PAREN + | L_PAREN WS+ sentence R_PAREN { + /* TODO */ + $result = null; } | non_text_value { + $result = ($non_text_value.result); } ; -non_text_value: +non_text_value +returns [ValueNode result] +: IF_ELSE_KW value WS+ value WS+ value R_PAREN { + /* TODO */ + $result = null; } | COND_KW value_cond_list R_PAREN { + /* TODO */ + $result = null; } | boolean_expression { + $result = ($boolean_expression.result); } | math_expression { + $result = ($math_expression.result); } | CAST_KW WORD WORD value R_PAREN { + /* TODO */ + $result = null; } | value_reference { + /* TODO */ + $result = null; } | SET_KW value WS+ value_reference R_PAREN { + /* TODO */ + $result = null; } ; @@ -378,8 +712,25 @@ value_cond_list: } ; -value_list: - value* (WS+ value)* +value_list +returns [List<ValueNode> result] +@init +{ + $result = new ArrayList<ValueNode>(); +} +: + ( + value + { + ($result).add(($value.result)); + } + )* + (WS+ + value + { + ($result).add(($value.result)); + } + )* { } ; diff --git a/src/core/src/tonkadur/parser/Origin.java b/src/core/src/tonkadur/parser/Origin.java index 9fa7939..f6f2d29 100644 --- a/src/core/src/tonkadur/parser/Origin.java +++ b/src/core/src/tonkadur/parser/Origin.java @@ -30,4 +30,15 @@ public class Origin { return location; } + + @Override + public String toString() + { + final StringBuilder sb = new StringBuilder(); + + sb.append(context.toString()); + sb.append(location.toString()); + + return sb.toString(); + } } |


