You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nlpcraft.apache.org by ar...@apache.org on 2021/02/02 23:23:44 UTC

[incubator-nlpcraft] 01/02: WIP.

This is an automated email from the ASF dual-hosted git repository.

aradzinski pushed a commit to branch NLPCRAFT-206
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git

commit 546d235246b2f803ef5b0a3c848ed981fdf002bf
Author: Aaron Radzinski <ar...@datalingvo.com>
AuthorDate: Tue Feb 2 10:06:42 2021 -0800

    WIP.
---
 .../model/intent/impl/antlr4/NCIntentDsl.g4        |  11 +-
 .../model/intent/impl/antlr4/NCIntentDsl.interp    |   5 +-
 .../model/intent/impl/antlr4/NCIntentDsl.tokens    |  22 +-
 .../impl/antlr4/NCIntentDslBaseListener.java       |  12 +
 .../intent/impl/antlr4/NCIntentDslLexer.interp     |   5 +-
 .../model/intent/impl/antlr4/NCIntentDslLexer.java | 222 +++----
 .../intent/impl/antlr4/NCIntentDslLexer.tokens     |  22 +-
 .../intent/impl/antlr4/NCIntentDslListener.java    |  10 +
 .../intent/impl/antlr4/NCIntentDslParser.java      | 718 ++++++++++++---------
 .../probe/mgrs/model/antlr4/NCSynonymDsl.g4        |  13 +-
 .../probe/mgrs/model/antlr4/NCSynonymDsl.interp    |   9 +-
 .../probe/mgrs/model/antlr4/NCSynonymDsl.tokens    |  42 +-
 .../model/antlr4/NCSynonymDslBaseListener.java     |  12 +
 .../mgrs/model/antlr4/NCSynonymDslLexer.interp     |  11 +-
 .../probe/mgrs/model/antlr4/NCSynonymDslLexer.java | 181 +++---
 .../mgrs/model/antlr4/NCSynonymDslLexer.tokens     |  42 +-
 .../mgrs/model/antlr4/NCSynonymDslListener.java    |  10 +
 .../mgrs/model/antlr4/NCSynonymDslParser.java      | 526 +++++++++------
 18 files changed, 1120 insertions(+), 753 deletions(-)

diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDsl.g4 b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDsl.g4
index 1418b8d..09c1ee2 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDsl.g4
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDsl.g4
@@ -48,7 +48,15 @@ item
 pred: expr PRED_OP expr;
 expr
     : val
-    | ID LPAREN expr RPAREN // Buit-in function call.
+    | LPAREN expr RPAREN
+    | expr mathOp expr
+    | ID LPAREN expr? RPAREN // Buit-in function call.
+    ;
+mathOp
+    : MINUS
+    | PLUS
+    | STAR
+    | DEVIDE
     ;
 val
     : singleVal
@@ -135,6 +143,7 @@ EQ: '=';
 PLUS: '+';
 QUESTION: '?';
 STAR: '*';
+DEVIDE: '/';
 DOLLAR: '$';
 POWER: '^';
 BOOL: 'true' | 'false';
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDsl.interp b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDsl.interp
index bc20478..133ddba 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDsl.interp
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDsl.interp
@@ -41,6 +41,7 @@ null
 '+'
 '?'
 '*'
+'/'
 '$'
 '^'
 null
@@ -93,6 +94,7 @@ EQ
 PLUS
 QUESTION
 STAR
+DEVIDE
 DOLLAR
 POWER
 BOOL
@@ -118,6 +120,7 @@ termId
 item
 pred
 expr
+mathOp
 val
 singleVal
 tokQual
@@ -132,4 +135,4 @@ minMaxRange
 
 
 atn:
-[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 51, 276, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 3, 2, 3, 2, 5, 2, 57, 10, 2, 3, 2, 5, 2, 60, 10, 2, 3, 2, 5, 2, 63, 10,  [...]
\ No newline at end of file
+[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 52, 295, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 3, 2, 3, 2, 5, 2, 59, 10, 2, 3, 2, 5, 2, 62, 10, 2, 3, 2,  [...]
\ No newline at end of file
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDsl.tokens b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDsl.tokens
index 5175019..7b0f50b 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDsl.tokens
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDsl.tokens
@@ -39,14 +39,15 @@ EQ=38
 PLUS=39
 QUESTION=40
 STAR=41
-DOLLAR=42
-POWER=43
-BOOL=44
-INT=45
-EXP=46
-ID=47
-WS=48
-ErrorCharacter=49
+DEVIDE=42
+DOLLAR=43
+POWER=44
+BOOL=45
+INT=46
+EXP=47
+ID=48
+WS=49
+ErrorCharacter=50
 'intent'=1
 'ordered'=2
 'flow'=3
@@ -85,5 +86,6 @@ ErrorCharacter=49
 '+'=39
 '?'=40
 '*'=41
-'$'=42
-'^'=43
+'/'=42
+'$'=43
+'^'=44
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslBaseListener.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslBaseListener.java
index a6d7267..689fd21 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslBaseListener.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslBaseListener.java
@@ -196,6 +196,18 @@ public class NCIntentDslBaseListener implements NCIntentDslListener {
 	 *
 	 * <p>The default implementation does nothing.</p>
 	 */
+	@Override public void enterMathOp(NCIntentDslParser.MathOpContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
+	@Override public void exitMathOp(NCIntentDslParser.MathOpContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
 	@Override public void enterVal(NCIntentDslParser.ValContext ctx) { }
 	/**
 	 * {@inheritDoc}
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslLexer.interp b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslLexer.interp
index ee91550..4183c24 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslLexer.interp
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslLexer.interp
@@ -41,6 +41,7 @@ null
 '+'
 '?'
 '*'
+'/'
 '$'
 '^'
 null
@@ -93,6 +94,7 @@ EQ
 PLUS
 QUESTION
 STAR
+DEVIDE
 DOLLAR
 POWER
 BOOL
@@ -144,6 +146,7 @@ EQ
 PLUS
 QUESTION
 STAR
+DEVIDE
 DOLLAR
 POWER
 BOOL
@@ -161,4 +164,4 @@ mode names:
 DEFAULT_MODE
 
 atn:
-[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 51, 332, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9,  [...]
\ No newline at end of file
+[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 52, 336, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9,  [...]
\ No newline at end of file
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslLexer.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslLexer.java
index dd551a5..629af31 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslLexer.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslLexer.java
@@ -22,7 +22,8 @@ public class NCIntentDslLexer extends Lexer {
 		PRED_OP=17, AND=18, OR=19, VERT=20, EXCL=21, LPAREN=22, RPAREN=23, LCURLY=24, 
 		RCURLY=25, SQUOTE=26, DQUOTE=27, TILDA=28, RIGHT=29, LBR=30, RBR=31, POUND=32, 
 		COMMA=33, COLON=34, MINUS=35, DOT=36, UNDERSCORE=37, EQ=38, PLUS=39, QUESTION=40, 
-		STAR=41, DOLLAR=42, POWER=43, BOOL=44, INT=45, EXP=46, ID=47, WS=48, ErrorCharacter=49;
+		STAR=41, DEVIDE=42, DOLLAR=43, POWER=44, BOOL=45, INT=46, EXP=47, ID=48, 
+		WS=49, ErrorCharacter=50;
 	public static String[] channelNames = {
 		"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
 	};
@@ -38,7 +39,7 @@ public class NCIntentDslLexer extends Lexer {
 			"AND", "OR", "VERT", "EXCL", "LPAREN", "RPAREN", "LCURLY", "RCURLY", 
 			"SQUOTE", "DQUOTE", "TILDA", "RIGHT", "LBR", "RBR", "POUND", "COMMA", 
 			"COLON", "MINUS", "DOT", "UNDERSCORE", "EQ", "PLUS", "QUESTION", "STAR", 
-			"DOLLAR", "POWER", "BOOL", "INT", "EXP", "ID", "WS", "ErrorCharacter"
+			"DEVIDE", "DOLLAR", "POWER", "BOOL", "INT", "EXP", "ID", "WS", "ErrorCharacter"
 		};
 	}
 	public static final String[] ruleNames = makeRuleNames();
@@ -50,7 +51,7 @@ public class NCIntentDslLexer extends Lexer {
 			"'ancestors'", "'value'", null, null, null, "'&&'", "'||'", "'|'", "'!'", 
 			"'('", "')'", "'{'", "'}'", "'''", "'\"'", "'~'", "'>>'", "'['", "']'", 
 			"'#'", "','", "':'", "'-'", "'.'", "'_'", "'='", "'+'", "'?'", "'*'", 
-			"'$'", "'^'"
+			"'/'", "'$'", "'^'"
 		};
 	}
 	private static final String[] _LITERAL_NAMES = makeLiteralNames();
@@ -60,8 +61,8 @@ public class NCIntentDslLexer extends Lexer {
 			null, null, null, "SQSTRING", "DQSTRING", "PRED_OP", "AND", "OR", "VERT", 
 			"EXCL", "LPAREN", "RPAREN", "LCURLY", "RCURLY", "SQUOTE", "DQUOTE", "TILDA", 
 			"RIGHT", "LBR", "RBR", "POUND", "COMMA", "COLON", "MINUS", "DOT", "UNDERSCORE", 
-			"EQ", "PLUS", "QUESTION", "STAR", "DOLLAR", "POWER", "BOOL", "INT", "EXP", 
-			"ID", "WS", "ErrorCharacter"
+			"EQ", "PLUS", "QUESTION", "STAR", "DEVIDE", "DOLLAR", "POWER", "BOOL", 
+			"INT", "EXP", "ID", "WS", "ErrorCharacter"
 		};
 	}
 	private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames();
@@ -123,116 +124,117 @@ public class NCIntentDslLexer extends Lexer {
 	public ATN getATN() { return _ATN; }
 
 	public static final String _serializedATN =
-		"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\63\u014c\b\1\4\2"+
+		"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\64\u0150\b\1\4\2"+
 		"\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4"+
 		"\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22"+
 		"\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31"+
 		"\t\31\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t"+
 		" \4!\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t"+
-		"+\4,\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\3\2\3\2\3\2\3"+
-		"\2\3\2\3\2\3\2\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\4\3\4\3\4\3\4\3\4\3\5"+
-		"\3\5\3\5\3\5\3\5\3\6\3\6\3\6\3\6\3\6\3\7\3\7\3\7\3\7\3\7\3\b\3\b\3\b\3"+
-		"\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\13"+
-		"\3\13\3\13\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\r\3\r\3\r"+
-		"\3\r\3\r\3\r\3\r\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\17"+
-		"\3\17\3\17\3\17\3\17\3\17\3\20\3\20\7\20\u00c4\n\20\f\20\16\20\u00c7\13"+
-		"\20\3\20\3\20\3\21\3\21\7\21\u00cd\n\21\f\21\16\21\u00d0\13\21\3\21\3"+
-		"\21\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\5"+
-		"\22\u00e1\n\22\3\23\3\23\3\23\3\24\3\24\3\24\3\25\3\25\3\26\3\26\3\27"+
-		"\3\27\3\30\3\30\3\31\3\31\3\32\3\32\3\33\3\33\3\34\3\34\3\35\3\35\3\36"+
-		"\3\36\3\36\3\37\3\37\3 \3 \3!\3!\3\"\3\"\3#\3#\3$\3$\3%\3%\3&\3&\3\'\3"+
-		"\'\3(\3(\3)\3)\3*\3*\3+\3+\3,\3,\3-\3-\3-\3-\3-\3-\3-\3-\3-\5-\u0123\n"+
-		"-\3.\3.\3.\7.\u0128\n.\f.\16.\u012b\13.\5.\u012d\n.\3/\3/\6/\u0131\n/"+
-		"\r/\16/\u0132\3\60\3\60\6\60\u0137\n\60\r\60\16\60\u0138\3\60\3\60\3\60"+
-		"\3\60\7\60\u013f\n\60\f\60\16\60\u0142\13\60\3\61\6\61\u0145\n\61\r\61"+
-		"\16\61\u0146\3\61\3\61\3\62\3\62\2\2\63\3\3\5\4\7\5\t\6\13\7\r\b\17\t"+
-		"\21\n\23\13\25\f\27\r\31\16\33\17\35\20\37\21!\22#\23%\24\'\25)\26+\27"+
-		"-\30/\31\61\32\63\33\65\34\67\359\36;\37= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W"+
-		"-Y.[/]\60_\61a\62c\63\3\2\13\3\2))\3\2$$\4\2>>@@\3\2\63;\4\2\62;aa\3\2"+
-		"\62;\4\2C\\c|\5\2\62;C\\c|\5\2\13\f\16\17\"\"\2\u015e\2\3\3\2\2\2\2\5"+
-		"\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2"+
-		"\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33"+
-		"\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2"+
-		"\'\3\2\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2"+
-		"\63\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2"+
-		"\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K"+
-		"\3\2\2\2\2M\3\2\2\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2"+
-		"\2\2\2Y\3\2\2\2\2[\3\2\2\2\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2\2c\3\2\2\2"+
-		"\3e\3\2\2\2\5l\3\2\2\2\7t\3\2\2\2\ty\3\2\2\2\13~\3\2\2\2\r\u0083\3\2\2"+
-		"\2\17\u0088\3\2\2\2\21\u008b\3\2\2\2\23\u0093\3\2\2\2\25\u009c\3\2\2\2"+
-		"\27\u00a3\3\2\2\2\31\u00aa\3\2\2\2\33\u00b1\3\2\2\2\35\u00bb\3\2\2\2\37"+
-		"\u00c1\3\2\2\2!\u00ca\3\2\2\2#\u00e0\3\2\2\2%\u00e2\3\2\2\2\'\u00e5\3"+
-		"\2\2\2)\u00e8\3\2\2\2+\u00ea\3\2\2\2-\u00ec\3\2\2\2/\u00ee\3\2\2\2\61"+
-		"\u00f0\3\2\2\2\63\u00f2\3\2\2\2\65\u00f4\3\2\2\2\67\u00f6\3\2\2\29\u00f8"+
-		"\3\2\2\2;\u00fa\3\2\2\2=\u00fd\3\2\2\2?\u00ff\3\2\2\2A\u0101\3\2\2\2C"+
-		"\u0103\3\2\2\2E\u0105\3\2\2\2G\u0107\3\2\2\2I\u0109\3\2\2\2K\u010b\3\2"+
-		"\2\2M\u010d\3\2\2\2O\u010f\3\2\2\2Q\u0111\3\2\2\2S\u0113\3\2\2\2U\u0115"+
-		"\3\2\2\2W\u0117\3\2\2\2Y\u0122\3\2\2\2[\u012c\3\2\2\2]\u012e\3\2\2\2_"+
-		"\u0136\3\2\2\2a\u0144\3\2\2\2c\u014a\3\2\2\2ef\7k\2\2fg\7p\2\2gh\7v\2"+
-		"\2hi\7g\2\2ij\7p\2\2jk\7v\2\2k\4\3\2\2\2lm\7q\2\2mn\7t\2\2no\7f\2\2op"+
-		"\7g\2\2pq\7t\2\2qr\7g\2\2rs\7f\2\2s\6\3\2\2\2tu\7h\2\2uv\7n\2\2vw\7q\2"+
-		"\2wx\7y\2\2x\b\3\2\2\2yz\7o\2\2z{\7g\2\2{|\7v\2\2|}\7c\2\2}\n\3\2\2\2"+
-		"~\177\7p\2\2\177\u0080\7w\2\2\u0080\u0081\7n\2\2\u0081\u0082\7n\2\2\u0082"+
-		"\f\3\2\2\2\u0083\u0084\7v\2\2\u0084\u0085\7g\2\2\u0085\u0086\7t\2\2\u0086"+
-		"\u0087\7o\2\2\u0087\16\3\2\2\2\u0088\u0089\7k\2\2\u0089\u008a\7f\2\2\u008a"+
-		"\20\3\2\2\2\u008b\u008c\7c\2\2\u008c\u008d\7n\2\2\u008d\u008e\7k\2\2\u008e"+
-		"\u008f\7c\2\2\u008f\u0090\7u\2\2\u0090\u0091\7g\2\2\u0091\u0092\7u\2\2"+
-		"\u0092\22\3\2\2\2\u0093\u0094\7u\2\2\u0094\u0095\7v\2\2\u0095\u0096\7"+
-		"c\2\2\u0096\u0097\7t\2\2\u0097\u0098\7v\2\2\u0098\u0099\7k\2\2\u0099\u009a"+
-		"\7f\2\2\u009a\u009b\7z\2\2\u009b\24\3\2\2\2\u009c\u009d\7g\2\2\u009d\u009e"+
-		"\7p\2\2\u009e\u009f\7f\2\2\u009f\u00a0\7k\2\2\u00a0\u00a1\7f\2\2\u00a1"+
-		"\u00a2\7z\2\2\u00a2\26\3\2\2\2\u00a3\u00a4\7r\2\2\u00a4\u00a5\7c\2\2\u00a5"+
-		"\u00a6\7t\2\2\u00a6\u00a7\7g\2\2\u00a7\u00a8\7p\2\2\u00a8\u00a9\7v\2\2"+
-		"\u00a9\30\3\2\2\2\u00aa\u00ab\7i\2\2\u00ab\u00ac\7t\2\2\u00ac\u00ad\7"+
-		"q\2\2\u00ad\u00ae\7w\2\2\u00ae\u00af\7r\2\2\u00af\u00b0\7u\2\2\u00b0\32"+
-		"\3\2\2\2\u00b1\u00b2\7c\2\2\u00b2\u00b3\7p\2\2\u00b3\u00b4\7e\2\2\u00b4"+
-		"\u00b5\7g\2\2\u00b5\u00b6\7u\2\2\u00b6\u00b7\7v\2\2\u00b7\u00b8\7q\2\2"+
-		"\u00b8\u00b9\7t\2\2\u00b9\u00ba\7u\2\2\u00ba\34\3\2\2\2\u00bb\u00bc\7"+
-		"x\2\2\u00bc\u00bd\7c\2\2\u00bd\u00be\7n\2\2\u00be\u00bf\7w\2\2\u00bf\u00c0"+
-		"\7g\2\2\u00c0\36\3\2\2\2\u00c1\u00c5\5\65\33\2\u00c2\u00c4\n\2\2\2\u00c3"+
-		"\u00c2\3\2\2\2\u00c4\u00c7\3\2\2\2\u00c5\u00c3\3\2\2\2\u00c5\u00c6\3\2"+
-		"\2\2\u00c6\u00c8\3\2\2\2\u00c7\u00c5\3\2\2\2\u00c8\u00c9\5\65\33\2\u00c9"+
-		" \3\2\2\2\u00ca\u00ce\5\67\34\2\u00cb\u00cd\n\3\2\2\u00cc\u00cb\3\2\2"+
-		"\2\u00cd\u00d0\3\2\2\2\u00ce\u00cc\3\2\2\2\u00ce\u00cf\3\2\2\2\u00cf\u00d1"+
-		"\3\2\2\2\u00d0\u00ce\3\2\2\2\u00d1\u00d2\5\67\34\2\u00d2\"\3\2\2\2\u00d3"+
-		"\u00d4\7?\2\2\u00d4\u00e1\7?\2\2\u00d5\u00d6\7#\2\2\u00d6\u00e1\7?\2\2"+
-		"\u00d7\u00d8\7@\2\2\u00d8\u00e1\7?\2\2\u00d9\u00da\7>\2\2\u00da\u00e1"+
-		"\7?\2\2\u00db\u00e1\t\4\2\2\u00dc\u00dd\7B\2\2\u00dd\u00e1\7B\2\2\u00de"+
-		"\u00df\7#\2\2\u00df\u00e1\7B\2\2\u00e0\u00d3\3\2\2\2\u00e0\u00d5\3\2\2"+
-		"\2\u00e0\u00d7\3\2\2\2\u00e0\u00d9\3\2\2\2\u00e0\u00db\3\2\2\2\u00e0\u00dc"+
-		"\3\2\2\2\u00e0\u00de\3\2\2\2\u00e1$\3\2\2\2\u00e2\u00e3\7(\2\2\u00e3\u00e4"+
-		"\7(\2\2\u00e4&\3\2\2\2\u00e5\u00e6\7~\2\2\u00e6\u00e7\7~\2\2\u00e7(\3"+
-		"\2\2\2\u00e8\u00e9\7~\2\2\u00e9*\3\2\2\2\u00ea\u00eb\7#\2\2\u00eb,\3\2"+
-		"\2\2\u00ec\u00ed\7*\2\2\u00ed.\3\2\2\2\u00ee\u00ef\7+\2\2\u00ef\60\3\2"+
-		"\2\2\u00f0\u00f1\7}\2\2\u00f1\62\3\2\2\2\u00f2\u00f3\7\177\2\2\u00f3\64"+
-		"\3\2\2\2\u00f4\u00f5\7)\2\2\u00f5\66\3\2\2\2\u00f6\u00f7\7$\2\2\u00f7"+
-		"8\3\2\2\2\u00f8\u00f9\7\u0080\2\2\u00f9:\3\2\2\2\u00fa\u00fb\7@\2\2\u00fb"+
-		"\u00fc\7@\2\2\u00fc<\3\2\2\2\u00fd\u00fe\7]\2\2\u00fe>\3\2\2\2\u00ff\u0100"+
-		"\7_\2\2\u0100@\3\2\2\2\u0101\u0102\7%\2\2\u0102B\3\2\2\2\u0103\u0104\7"+
-		".\2\2\u0104D\3\2\2\2\u0105\u0106\7<\2\2\u0106F\3\2\2\2\u0107\u0108\7/"+
-		"\2\2\u0108H\3\2\2\2\u0109\u010a\7\60\2\2\u010aJ\3\2\2\2\u010b\u010c\7"+
-		"a\2\2\u010cL\3\2\2\2\u010d\u010e\7?\2\2\u010eN\3\2\2\2\u010f\u0110\7-"+
-		"\2\2\u0110P\3\2\2\2\u0111\u0112\7A\2\2\u0112R\3\2\2\2\u0113\u0114\7,\2"+
-		"\2\u0114T\3\2\2\2\u0115\u0116\7&\2\2\u0116V\3\2\2\2\u0117\u0118\7`\2\2"+
-		"\u0118X\3\2\2\2\u0119\u011a\7v\2\2\u011a\u011b\7t\2\2\u011b\u011c\7w\2"+
-		"\2\u011c\u0123\7g\2\2\u011d\u011e\7h\2\2\u011e\u011f\7c\2\2\u011f\u0120"+
-		"\7n\2\2\u0120\u0121\7u\2\2\u0121\u0123\7g\2\2\u0122\u0119\3\2\2\2\u0122"+
-		"\u011d\3\2\2\2\u0123Z\3\2\2\2\u0124\u012d\7\62\2\2\u0125\u0129\t\5\2\2"+
-		"\u0126\u0128\t\6\2\2\u0127\u0126\3\2\2\2\u0128\u012b\3\2\2\2\u0129\u0127"+
-		"\3\2\2\2\u0129\u012a\3\2\2\2\u012a\u012d\3\2\2\2\u012b\u0129\3\2\2\2\u012c"+
-		"\u0124\3\2\2\2\u012c\u0125\3\2\2\2\u012d\\\3\2\2\2\u012e\u0130\5I%\2\u012f"+
-		"\u0131\t\7\2\2\u0130\u012f\3\2\2\2\u0131\u0132\3\2\2\2\u0132\u0130\3\2"+
-		"\2\2\u0132\u0133\3\2\2\2\u0133^\3\2\2\2\u0134\u0137\5K&\2\u0135\u0137"+
-		"\t\b\2\2\u0136\u0134\3\2\2\2\u0136\u0135\3\2\2\2\u0137\u0138\3\2\2\2\u0138"+
-		"\u0136\3\2\2\2\u0138\u0139\3\2\2\2\u0139\u0140\3\2\2\2\u013a\u013f\t\t"+
-		"\2\2\u013b\u013f\5E#\2\u013c\u013f\5G$\2\u013d\u013f\5K&\2\u013e\u013a"+
-		"\3\2\2\2\u013e\u013b\3\2\2\2\u013e\u013c\3\2\2\2\u013e\u013d\3\2\2\2\u013f"+
-		"\u0142\3\2\2\2\u0140\u013e\3\2\2\2\u0140\u0141\3\2\2\2\u0141`\3\2\2\2"+
-		"\u0142\u0140\3\2\2\2\u0143\u0145\t\n\2\2\u0144\u0143\3\2\2\2\u0145\u0146"+
-		"\3\2\2\2\u0146\u0144\3\2\2\2\u0146\u0147\3\2\2\2\u0147\u0148\3\2\2\2\u0148"+
-		"\u0149\b\61\2\2\u0149b\3\2\2\2\u014a\u014b\13\2\2\2\u014bd\3\2\2\2\17"+
-		"\2\u00c5\u00ce\u00e0\u0122\u0129\u012c\u0132\u0136\u0138\u013e\u0140\u0146"+
-		"\3\b\2\2";
+		"+\4,\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63\3\2"+
+		"\3\2\3\2\3\2\3\2\3\2\3\2\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\4\3\4\3\4\3"+
+		"\4\3\4\3\5\3\5\3\5\3\5\3\5\3\6\3\6\3\6\3\6\3\6\3\7\3\7\3\7\3\7\3\7\3\b"+
+		"\3\b\3\b\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3"+
+		"\n\3\n\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\f\3\f"+
+		"\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3"+
+		"\16\3\16\3\17\3\17\3\17\3\17\3\17\3\17\3\20\3\20\7\20\u00c6\n\20\f\20"+
+		"\16\20\u00c9\13\20\3\20\3\20\3\21\3\21\7\21\u00cf\n\21\f\21\16\21\u00d2"+
+		"\13\21\3\21\3\21\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22"+
+		"\3\22\3\22\5\22\u00e3\n\22\3\23\3\23\3\23\3\24\3\24\3\24\3\25\3\25\3\26"+
+		"\3\26\3\27\3\27\3\30\3\30\3\31\3\31\3\32\3\32\3\33\3\33\3\34\3\34\3\35"+
+		"\3\35\3\36\3\36\3\36\3\37\3\37\3 \3 \3!\3!\3\"\3\"\3#\3#\3$\3$\3%\3%\3"+
+		"&\3&\3\'\3\'\3(\3(\3)\3)\3*\3*\3+\3+\3,\3,\3-\3-\3.\3.\3.\3.\3.\3.\3."+
+		"\3.\3.\5.\u0127\n.\3/\3/\3/\7/\u012c\n/\f/\16/\u012f\13/\5/\u0131\n/\3"+
+		"\60\3\60\6\60\u0135\n\60\r\60\16\60\u0136\3\61\3\61\6\61\u013b\n\61\r"+
+		"\61\16\61\u013c\3\61\3\61\3\61\3\61\7\61\u0143\n\61\f\61\16\61\u0146\13"+
+		"\61\3\62\6\62\u0149\n\62\r\62\16\62\u014a\3\62\3\62\3\63\3\63\2\2\64\3"+
+		"\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20\37"+
+		"\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67\359\36;\37="+
+		" ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62c\63e\64\3\2\13\3\2))\3\2"+
+		"$$\4\2>>@@\3\2\63;\4\2\62;aa\3\2\62;\4\2C\\c|\5\2\62;C\\c|\5\2\13\f\16"+
+		"\17\"\"\2\u0162\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3"+
+		"\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2"+
+		"\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3"+
+		"\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2"+
+		"\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\2"+
+		"9\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3"+
+		"\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2O\3\2\2\2\2Q\3\2\2"+
+		"\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y\3\2\2\2\2[\3\2\2\2\2]\3\2\2\2\2"+
+		"_\3\2\2\2\2a\3\2\2\2\2c\3\2\2\2\2e\3\2\2\2\3g\3\2\2\2\5n\3\2\2\2\7v\3"+
+		"\2\2\2\t{\3\2\2\2\13\u0080\3\2\2\2\r\u0085\3\2\2\2\17\u008a\3\2\2\2\21"+
+		"\u008d\3\2\2\2\23\u0095\3\2\2\2\25\u009e\3\2\2\2\27\u00a5\3\2\2\2\31\u00ac"+
+		"\3\2\2\2\33\u00b3\3\2\2\2\35\u00bd\3\2\2\2\37\u00c3\3\2\2\2!\u00cc\3\2"+
+		"\2\2#\u00e2\3\2\2\2%\u00e4\3\2\2\2\'\u00e7\3\2\2\2)\u00ea\3\2\2\2+\u00ec"+
+		"\3\2\2\2-\u00ee\3\2\2\2/\u00f0\3\2\2\2\61\u00f2\3\2\2\2\63\u00f4\3\2\2"+
+		"\2\65\u00f6\3\2\2\2\67\u00f8\3\2\2\29\u00fa\3\2\2\2;\u00fc\3\2\2\2=\u00ff"+
+		"\3\2\2\2?\u0101\3\2\2\2A\u0103\3\2\2\2C\u0105\3\2\2\2E\u0107\3\2\2\2G"+
+		"\u0109\3\2\2\2I\u010b\3\2\2\2K\u010d\3\2\2\2M\u010f\3\2\2\2O\u0111\3\2"+
+		"\2\2Q\u0113\3\2\2\2S\u0115\3\2\2\2U\u0117\3\2\2\2W\u0119\3\2\2\2Y\u011b"+
+		"\3\2\2\2[\u0126\3\2\2\2]\u0130\3\2\2\2_\u0132\3\2\2\2a\u013a\3\2\2\2c"+
+		"\u0148\3\2\2\2e\u014e\3\2\2\2gh\7k\2\2hi\7p\2\2ij\7v\2\2jk\7g\2\2kl\7"+
+		"p\2\2lm\7v\2\2m\4\3\2\2\2no\7q\2\2op\7t\2\2pq\7f\2\2qr\7g\2\2rs\7t\2\2"+
+		"st\7g\2\2tu\7f\2\2u\6\3\2\2\2vw\7h\2\2wx\7n\2\2xy\7q\2\2yz\7y\2\2z\b\3"+
+		"\2\2\2{|\7o\2\2|}\7g\2\2}~\7v\2\2~\177\7c\2\2\177\n\3\2\2\2\u0080\u0081"+
+		"\7p\2\2\u0081\u0082\7w\2\2\u0082\u0083\7n\2\2\u0083\u0084\7n\2\2\u0084"+
+		"\f\3\2\2\2\u0085\u0086\7v\2\2\u0086\u0087\7g\2\2\u0087\u0088\7t\2\2\u0088"+
+		"\u0089\7o\2\2\u0089\16\3\2\2\2\u008a\u008b\7k\2\2\u008b\u008c\7f\2\2\u008c"+
+		"\20\3\2\2\2\u008d\u008e\7c\2\2\u008e\u008f\7n\2\2\u008f\u0090\7k\2\2\u0090"+
+		"\u0091\7c\2\2\u0091\u0092\7u\2\2\u0092\u0093\7g\2\2\u0093\u0094\7u\2\2"+
+		"\u0094\22\3\2\2\2\u0095\u0096\7u\2\2\u0096\u0097\7v\2\2\u0097\u0098\7"+
+		"c\2\2\u0098\u0099\7t\2\2\u0099\u009a\7v\2\2\u009a\u009b\7k\2\2\u009b\u009c"+
+		"\7f\2\2\u009c\u009d\7z\2\2\u009d\24\3\2\2\2\u009e\u009f\7g\2\2\u009f\u00a0"+
+		"\7p\2\2\u00a0\u00a1\7f\2\2\u00a1\u00a2\7k\2\2\u00a2\u00a3\7f\2\2\u00a3"+
+		"\u00a4\7z\2\2\u00a4\26\3\2\2\2\u00a5\u00a6\7r\2\2\u00a6\u00a7\7c\2\2\u00a7"+
+		"\u00a8\7t\2\2\u00a8\u00a9\7g\2\2\u00a9\u00aa\7p\2\2\u00aa\u00ab\7v\2\2"+
+		"\u00ab\30\3\2\2\2\u00ac\u00ad\7i\2\2\u00ad\u00ae\7t\2\2\u00ae\u00af\7"+
+		"q\2\2\u00af\u00b0\7w\2\2\u00b0\u00b1\7r\2\2\u00b1\u00b2\7u\2\2\u00b2\32"+
+		"\3\2\2\2\u00b3\u00b4\7c\2\2\u00b4\u00b5\7p\2\2\u00b5\u00b6\7e\2\2\u00b6"+
+		"\u00b7\7g\2\2\u00b7\u00b8\7u\2\2\u00b8\u00b9\7v\2\2\u00b9\u00ba\7q\2\2"+
+		"\u00ba\u00bb\7t\2\2\u00bb\u00bc\7u\2\2\u00bc\34\3\2\2\2\u00bd\u00be\7"+
+		"x\2\2\u00be\u00bf\7c\2\2\u00bf\u00c0\7n\2\2\u00c0\u00c1\7w\2\2\u00c1\u00c2"+
+		"\7g\2\2\u00c2\36\3\2\2\2\u00c3\u00c7\5\65\33\2\u00c4\u00c6\n\2\2\2\u00c5"+
+		"\u00c4\3\2\2\2\u00c6\u00c9\3\2\2\2\u00c7\u00c5\3\2\2\2\u00c7\u00c8\3\2"+
+		"\2\2\u00c8\u00ca\3\2\2\2\u00c9\u00c7\3\2\2\2\u00ca\u00cb\5\65\33\2\u00cb"+
+		" \3\2\2\2\u00cc\u00d0\5\67\34\2\u00cd\u00cf\n\3\2\2\u00ce\u00cd\3\2\2"+
+		"\2\u00cf\u00d2\3\2\2\2\u00d0\u00ce\3\2\2\2\u00d0\u00d1\3\2\2\2\u00d1\u00d3"+
+		"\3\2\2\2\u00d2\u00d0\3\2\2\2\u00d3\u00d4\5\67\34\2\u00d4\"\3\2\2\2\u00d5"+
+		"\u00d6\7?\2\2\u00d6\u00e3\7?\2\2\u00d7\u00d8\7#\2\2\u00d8\u00e3\7?\2\2"+
+		"\u00d9\u00da\7@\2\2\u00da\u00e3\7?\2\2\u00db\u00dc\7>\2\2\u00dc\u00e3"+
+		"\7?\2\2\u00dd\u00e3\t\4\2\2\u00de\u00df\7B\2\2\u00df\u00e3\7B\2\2\u00e0"+
+		"\u00e1\7#\2\2\u00e1\u00e3\7B\2\2\u00e2\u00d5\3\2\2\2\u00e2\u00d7\3\2\2"+
+		"\2\u00e2\u00d9\3\2\2\2\u00e2\u00db\3\2\2\2\u00e2\u00dd\3\2\2\2\u00e2\u00de"+
+		"\3\2\2\2\u00e2\u00e0\3\2\2\2\u00e3$\3\2\2\2\u00e4\u00e5\7(\2\2\u00e5\u00e6"+
+		"\7(\2\2\u00e6&\3\2\2\2\u00e7\u00e8\7~\2\2\u00e8\u00e9\7~\2\2\u00e9(\3"+
+		"\2\2\2\u00ea\u00eb\7~\2\2\u00eb*\3\2\2\2\u00ec\u00ed\7#\2\2\u00ed,\3\2"+
+		"\2\2\u00ee\u00ef\7*\2\2\u00ef.\3\2\2\2\u00f0\u00f1\7+\2\2\u00f1\60\3\2"+
+		"\2\2\u00f2\u00f3\7}\2\2\u00f3\62\3\2\2\2\u00f4\u00f5\7\177\2\2\u00f5\64"+
+		"\3\2\2\2\u00f6\u00f7\7)\2\2\u00f7\66\3\2\2\2\u00f8\u00f9\7$\2\2\u00f9"+
+		"8\3\2\2\2\u00fa\u00fb\7\u0080\2\2\u00fb:\3\2\2\2\u00fc\u00fd\7@\2\2\u00fd"+
+		"\u00fe\7@\2\2\u00fe<\3\2\2\2\u00ff\u0100\7]\2\2\u0100>\3\2\2\2\u0101\u0102"+
+		"\7_\2\2\u0102@\3\2\2\2\u0103\u0104\7%\2\2\u0104B\3\2\2\2\u0105\u0106\7"+
+		".\2\2\u0106D\3\2\2\2\u0107\u0108\7<\2\2\u0108F\3\2\2\2\u0109\u010a\7/"+
+		"\2\2\u010aH\3\2\2\2\u010b\u010c\7\60\2\2\u010cJ\3\2\2\2\u010d\u010e\7"+
+		"a\2\2\u010eL\3\2\2\2\u010f\u0110\7?\2\2\u0110N\3\2\2\2\u0111\u0112\7-"+
+		"\2\2\u0112P\3\2\2\2\u0113\u0114\7A\2\2\u0114R\3\2\2\2\u0115\u0116\7,\2"+
+		"\2\u0116T\3\2\2\2\u0117\u0118\7\61\2\2\u0118V\3\2\2\2\u0119\u011a\7&\2"+
+		"\2\u011aX\3\2\2\2\u011b\u011c\7`\2\2\u011cZ\3\2\2\2\u011d\u011e\7v\2\2"+
+		"\u011e\u011f\7t\2\2\u011f\u0120\7w\2\2\u0120\u0127\7g\2\2\u0121\u0122"+
+		"\7h\2\2\u0122\u0123\7c\2\2\u0123\u0124\7n\2\2\u0124\u0125\7u\2\2\u0125"+
+		"\u0127\7g\2\2\u0126\u011d\3\2\2\2\u0126\u0121\3\2\2\2\u0127\\\3\2\2\2"+
+		"\u0128\u0131\7\62\2\2\u0129\u012d\t\5\2\2\u012a\u012c\t\6\2\2\u012b\u012a"+
+		"\3\2\2\2\u012c\u012f\3\2\2\2\u012d\u012b\3\2\2\2\u012d\u012e\3\2\2\2\u012e"+
+		"\u0131\3\2\2\2\u012f\u012d\3\2\2\2\u0130\u0128\3\2\2\2\u0130\u0129\3\2"+
+		"\2\2\u0131^\3\2\2\2\u0132\u0134\5I%\2\u0133\u0135\t\7\2\2\u0134\u0133"+
+		"\3\2\2\2\u0135\u0136\3\2\2\2\u0136\u0134\3\2\2\2\u0136\u0137\3\2\2\2\u0137"+
+		"`\3\2\2\2\u0138\u013b\5K&\2\u0139\u013b\t\b\2\2\u013a\u0138\3\2\2\2\u013a"+
+		"\u0139\3\2\2\2\u013b\u013c\3\2\2\2\u013c\u013a\3\2\2\2\u013c\u013d\3\2"+
+		"\2\2\u013d\u0144\3\2\2\2\u013e\u0143\t\t\2\2\u013f\u0143\5E#\2\u0140\u0143"+
+		"\5G$\2\u0141\u0143\5K&\2\u0142\u013e\3\2\2\2\u0142\u013f\3\2\2\2\u0142"+
+		"\u0140\3\2\2\2\u0142\u0141\3\2\2\2\u0143\u0146\3\2\2\2\u0144\u0142\3\2"+
+		"\2\2\u0144\u0145\3\2\2\2\u0145b\3\2\2\2\u0146\u0144\3\2\2\2\u0147\u0149"+
+		"\t\n\2\2\u0148\u0147\3\2\2\2\u0149\u014a\3\2\2\2\u014a\u0148\3\2\2\2\u014a"+
+		"\u014b\3\2\2\2\u014b\u014c\3\2\2\2\u014c\u014d\b\62\2\2\u014dd\3\2\2\2"+
+		"\u014e\u014f\13\2\2\2\u014ff\3\2\2\2\17\2\u00c7\u00d0\u00e2\u0126\u012d"+
+		"\u0130\u0136\u013a\u013c\u0142\u0144\u014a\3\b\2\2";
 	public static final ATN _ATN =
 		new ATNDeserializer().deserialize(_serializedATN.toCharArray());
 	static {
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslLexer.tokens b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslLexer.tokens
index 5175019..7b0f50b 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslLexer.tokens
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslLexer.tokens
@@ -39,14 +39,15 @@ EQ=38
 PLUS=39
 QUESTION=40
 STAR=41
-DOLLAR=42
-POWER=43
-BOOL=44
-INT=45
-EXP=46
-ID=47
-WS=48
-ErrorCharacter=49
+DEVIDE=42
+DOLLAR=43
+POWER=44
+BOOL=45
+INT=46
+EXP=47
+ID=48
+WS=49
+ErrorCharacter=50
 'intent'=1
 'ordered'=2
 'flow'=3
@@ -85,5 +86,6 @@ ErrorCharacter=49
 '+'=39
 '?'=40
 '*'=41
-'$'=42
-'^'=43
+'/'=42
+'$'=43
+'^'=44
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslListener.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslListener.java
index eea29a5..c09ec34 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslListener.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslListener.java
@@ -158,6 +158,16 @@ public interface NCIntentDslListener extends ParseTreeListener {
 	 */
 	void exitExpr(NCIntentDslParser.ExprContext ctx);
 	/**
+	 * Enter a parse tree produced by {@link NCIntentDslParser#mathOp}.
+	 * @param ctx the parse tree
+	 */
+	void enterMathOp(NCIntentDslParser.MathOpContext ctx);
+	/**
+	 * Exit a parse tree produced by {@link NCIntentDslParser#mathOp}.
+	 * @param ctx the parse tree
+	 */
+	void exitMathOp(NCIntentDslParser.MathOpContext ctx);
+	/**
 	 * Enter a parse tree produced by {@link NCIntentDslParser#val}.
 	 * @param ctx the parse tree
 	 */
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslParser.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslParser.java
index bd52388..6b04ee5 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslParser.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslParser.java
@@ -22,20 +22,23 @@ public class NCIntentDslParser extends Parser {
 		PRED_OP=17, AND=18, OR=19, VERT=20, EXCL=21, LPAREN=22, RPAREN=23, LCURLY=24, 
 		RCURLY=25, SQUOTE=26, DQUOTE=27, TILDA=28, RIGHT=29, LBR=30, RBR=31, POUND=32, 
 		COMMA=33, COLON=34, MINUS=35, DOT=36, UNDERSCORE=37, EQ=38, PLUS=39, QUESTION=40, 
-		STAR=41, DOLLAR=42, POWER=43, BOOL=44, INT=45, EXP=46, ID=47, WS=48, ErrorCharacter=49;
+		STAR=41, DEVIDE=42, DOLLAR=43, POWER=44, BOOL=45, INT=46, EXP=47, ID=48, 
+		WS=49, ErrorCharacter=50;
 	public static final int
 		RULE_intent = 0, RULE_intentId = 1, RULE_orderedDecl = 2, RULE_flowDecl = 3, 
 		RULE_metaDecl = 4, RULE_metaList = 5, RULE_metaItem = 6, RULE_metaItemRval = 7, 
 		RULE_terms = 8, RULE_termEq = 9, RULE_term = 10, RULE_termId = 11, RULE_item = 12, 
-		RULE_pred = 13, RULE_expr = 14, RULE_val = 15, RULE_singleVal = 16, RULE_tokQual = 17, 
-		RULE_tokQualPart = 18, RULE_tokMeta = 19, RULE_modelMeta = 20, RULE_intentMeta = 21, 
-		RULE_qstring = 22, RULE_minMax = 23, RULE_minMaxShortcut = 24, RULE_minMaxRange = 25;
+		RULE_pred = 13, RULE_expr = 14, RULE_mathOp = 15, RULE_val = 16, RULE_singleVal = 17, 
+		RULE_tokQual = 18, RULE_tokQualPart = 19, RULE_tokMeta = 20, RULE_modelMeta = 21, 
+		RULE_intentMeta = 22, RULE_qstring = 23, RULE_minMax = 24, RULE_minMaxShortcut = 25, 
+		RULE_minMaxRange = 26;
 	private static String[] makeRuleNames() {
 		return new String[] {
 			"intent", "intentId", "orderedDecl", "flowDecl", "metaDecl", "metaList", 
 			"metaItem", "metaItemRval", "terms", "termEq", "term", "termId", "item", 
-			"pred", "expr", "val", "singleVal", "tokQual", "tokQualPart", "tokMeta", 
-			"modelMeta", "intentMeta", "qstring", "minMax", "minMaxShortcut", "minMaxRange"
+			"pred", "expr", "mathOp", "val", "singleVal", "tokQual", "tokQualPart", 
+			"tokMeta", "modelMeta", "intentMeta", "qstring", "minMax", "minMaxShortcut", 
+			"minMaxRange"
 		};
 	}
 	public static final String[] ruleNames = makeRuleNames();
@@ -47,7 +50,7 @@ public class NCIntentDslParser extends Parser {
 			"'ancestors'", "'value'", null, null, null, "'&&'", "'||'", "'|'", "'!'", 
 			"'('", "')'", "'{'", "'}'", "'''", "'\"'", "'~'", "'>>'", "'['", "']'", 
 			"'#'", "','", "':'", "'-'", "'.'", "'_'", "'='", "'+'", "'?'", "'*'", 
-			"'$'", "'^'"
+			"'/'", "'$'", "'^'"
 		};
 	}
 	private static final String[] _LITERAL_NAMES = makeLiteralNames();
@@ -57,8 +60,8 @@ public class NCIntentDslParser extends Parser {
 			null, null, null, "SQSTRING", "DQSTRING", "PRED_OP", "AND", "OR", "VERT", 
 			"EXCL", "LPAREN", "RPAREN", "LCURLY", "RCURLY", "SQUOTE", "DQUOTE", "TILDA", 
 			"RIGHT", "LBR", "RBR", "POUND", "COMMA", "COLON", "MINUS", "DOT", "UNDERSCORE", 
-			"EQ", "PLUS", "QUESTION", "STAR", "DOLLAR", "POWER", "BOOL", "INT", "EXP", 
-			"ID", "WS", "ErrorCharacter"
+			"EQ", "PLUS", "QUESTION", "STAR", "DEVIDE", "DOLLAR", "POWER", "BOOL", 
+			"INT", "EXP", "ID", "WS", "ErrorCharacter"
 		};
 	}
 	private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames();
@@ -150,41 +153,41 @@ public class NCIntentDslParser extends Parser {
 		try {
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(52);
-			intentId();
 			setState(54);
+			intentId();
+			setState(56);
 			_errHandler.sync(this);
 			_la = _input.LA(1);
 			if (_la==T__1) {
 				{
-				setState(53);
+				setState(55);
 				orderedDecl();
 				}
 			}
 
-			setState(57);
+			setState(59);
 			_errHandler.sync(this);
 			_la = _input.LA(1);
 			if (_la==T__2) {
 				{
-				setState(56);
+				setState(58);
 				flowDecl();
 				}
 			}
 
-			setState(60);
+			setState(62);
 			_errHandler.sync(this);
 			_la = _input.LA(1);
 			if (_la==T__3) {
 				{
-				setState(59);
+				setState(61);
 				metaDecl();
 				}
 			}
 
-			setState(62);
+			setState(64);
 			terms(0);
-			setState(63);
+			setState(65);
 			match(EOF);
 			}
 		}
@@ -222,11 +225,11 @@ public class NCIntentDslParser extends Parser {
 		try {
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(65);
+			setState(67);
 			match(T__0);
-			setState(66);
+			setState(68);
 			match(EQ);
-			setState(67);
+			setState(69);
 			match(ID);
 			}
 		}
@@ -264,11 +267,11 @@ public class NCIntentDslParser extends Parser {
 		try {
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(69);
+			setState(71);
 			match(T__1);
-			setState(70);
+			setState(72);
 			match(EQ);
-			setState(71);
+			setState(73);
 			match(BOOL);
 			}
 		}
@@ -308,11 +311,11 @@ public class NCIntentDslParser extends Parser {
 		try {
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(73);
+			setState(75);
 			match(T__2);
-			setState(74);
+			setState(76);
 			match(EQ);
-			setState(75);
+			setState(77);
 			qstring();
 			}
 		}
@@ -355,23 +358,23 @@ public class NCIntentDslParser extends Parser {
 		try {
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(77);
+			setState(79);
 			match(T__3);
-			setState(78);
+			setState(80);
 			match(EQ);
-			setState(79);
-			match(LCURLY);
 			setState(81);
+			match(LCURLY);
+			setState(83);
 			_errHandler.sync(this);
 			_la = _input.LA(1);
 			if (_la==SQSTRING || _la==DQSTRING) {
 				{
-				setState(80);
+				setState(82);
 				metaList(0);
 				}
 			}
 
-			setState(83);
+			setState(85);
 			match(RCURLY);
 			}
 		}
@@ -424,11 +427,11 @@ public class NCIntentDslParser extends Parser {
 			enterOuterAlt(_localctx, 1);
 			{
 			{
-			setState(86);
+			setState(88);
 			metaItem();
 			}
 			_ctx.stop = _input.LT(-1);
-			setState(93);
+			setState(95);
 			_errHandler.sync(this);
 			_alt = getInterpreter().adaptivePredict(_input,4,_ctx);
 			while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
@@ -439,16 +442,16 @@ public class NCIntentDslParser extends Parser {
 					{
 					_localctx = new MetaListContext(_parentctx, _parentState);
 					pushNewRecursionContext(_localctx, _startState, RULE_metaList);
-					setState(88);
+					setState(90);
 					if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)");
-					setState(89);
+					setState(91);
 					match(COMMA);
-					setState(90);
+					setState(92);
 					metaItem();
 					}
 					} 
 				}
-				setState(95);
+				setState(97);
 				_errHandler.sync(this);
 				_alt = getInterpreter().adaptivePredict(_input,4,_ctx);
 			}
@@ -493,11 +496,11 @@ public class NCIntentDslParser extends Parser {
 		try {
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(96);
+			setState(98);
 			qstring();
-			setState(97);
+			setState(99);
 			match(COLON);
-			setState(98);
+			setState(100);
 			metaItemRval();
 			}
 		}
@@ -535,20 +538,20 @@ public class NCIntentDslParser extends Parser {
 		MetaItemRvalContext _localctx = new MetaItemRvalContext(_ctx, getState());
 		enterRule(_localctx, 14, RULE_metaItemRval);
 		try {
-			setState(103);
+			setState(105);
 			_errHandler.sync(this);
 			switch (_input.LA(1)) {
 			case T__4:
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(100);
+				setState(102);
 				match(T__4);
 				}
 				break;
 			case BOOL:
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(101);
+				setState(103);
 				match(BOOL);
 				}
 				break;
@@ -556,7 +559,7 @@ public class NCIntentDslParser extends Parser {
 			case DQSTRING:
 				enterOuterAlt(_localctx, 3);
 				{
-				setState(102);
+				setState(104);
 				qstring();
 				}
 				break;
@@ -612,11 +615,11 @@ public class NCIntentDslParser extends Parser {
 			enterOuterAlt(_localctx, 1);
 			{
 			{
-			setState(106);
+			setState(108);
 			term();
 			}
 			_ctx.stop = _input.LT(-1);
-			setState(112);
+			setState(114);
 			_errHandler.sync(this);
 			_alt = getInterpreter().adaptivePredict(_input,6,_ctx);
 			while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
@@ -627,14 +630,14 @@ public class NCIntentDslParser extends Parser {
 					{
 					_localctx = new TermsContext(_parentctx, _parentState);
 					pushNewRecursionContext(_localctx, _startState, RULE_terms);
-					setState(108);
+					setState(110);
 					if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)");
-					setState(109);
+					setState(111);
 					term();
 					}
 					} 
 				}
-				setState(114);
+				setState(116);
 				_errHandler.sync(this);
 				_alt = getInterpreter().adaptivePredict(_input,6,_ctx);
 			}
@@ -675,7 +678,7 @@ public class NCIntentDslParser extends Parser {
 		try {
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(115);
+			setState(117);
 			_la = _input.LA(1);
 			if ( !(_la==TILDA || _la==EQ) ) {
 			_errHandler.recoverInline(this);
@@ -734,32 +737,32 @@ public class NCIntentDslParser extends Parser {
 		try {
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(117);
-			match(T__5);
 			setState(119);
+			match(T__5);
+			setState(121);
 			_errHandler.sync(this);
 			_la = _input.LA(1);
 			if (_la==LPAREN) {
 				{
-				setState(118);
+				setState(120);
 				termId();
 				}
 			}
 
-			setState(121);
+			setState(123);
 			termEq();
-			setState(122);
+			setState(124);
 			match(LCURLY);
-			setState(123);
+			setState(125);
 			item(0);
-			setState(124);
-			match(RCURLY);
 			setState(126);
+			match(RCURLY);
+			setState(128);
 			_errHandler.sync(this);
 			switch ( getInterpreter().adaptivePredict(_input,8,_ctx) ) {
 			case 1:
 				{
-				setState(125);
+				setState(127);
 				minMax();
 				}
 				break;
@@ -801,11 +804,11 @@ public class NCIntentDslParser extends Parser {
 		try {
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(128);
+			setState(130);
 			match(LPAREN);
-			setState(129);
+			setState(131);
 			match(ID);
-			setState(130);
+			setState(132);
 			match(RPAREN);
 			}
 		}
@@ -865,36 +868,36 @@ public class NCIntentDslParser extends Parser {
 			int _alt;
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(140);
+			setState(142);
 			_errHandler.sync(this);
 			switch ( getInterpreter().adaptivePredict(_input,9,_ctx) ) {
 			case 1:
 				{
-				setState(133);
+				setState(135);
 				pred();
 				}
 				break;
 			case 2:
 				{
-				setState(134);
+				setState(136);
 				match(LPAREN);
-				setState(135);
+				setState(137);
 				item(0);
-				setState(136);
+				setState(138);
 				match(RPAREN);
 				}
 				break;
 			case 3:
 				{
-				setState(138);
+				setState(140);
 				match(EXCL);
-				setState(139);
+				setState(141);
 				item(1);
 				}
 				break;
 			}
 			_ctx.stop = _input.LT(-1);
-			setState(147);
+			setState(149);
 			_errHandler.sync(this);
 			_alt = getInterpreter().adaptivePredict(_input,10,_ctx);
 			while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
@@ -905,9 +908,9 @@ public class NCIntentDslParser extends Parser {
 					{
 					_localctx = new ItemContext(_parentctx, _parentState);
 					pushNewRecursionContext(_localctx, _startState, RULE_item);
-					setState(142);
+					setState(144);
 					if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)");
-					setState(143);
+					setState(145);
 					_la = _input.LA(1);
 					if ( !(_la==AND || _la==OR) ) {
 					_errHandler.recoverInline(this);
@@ -917,12 +920,12 @@ public class NCIntentDslParser extends Parser {
 						_errHandler.reportMatch(this);
 						consume();
 					}
-					setState(144);
+					setState(146);
 					item(3);
 					}
 					} 
 				}
-				setState(149);
+				setState(151);
 				_errHandler.sync(this);
 				_alt = getInterpreter().adaptivePredict(_input,10,_ctx);
 			}
@@ -967,12 +970,12 @@ public class NCIntentDslParser extends Parser {
 		try {
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(150);
-			expr();
-			setState(151);
-			match(PRED_OP);
 			setState(152);
-			expr();
+			expr(0);
+			setState(153);
+			match(PRED_OP);
+			setState(154);
+			expr(0);
 			}
 		}
 		catch (RecognitionException re) {
@@ -990,12 +993,18 @@ public class NCIntentDslParser extends Parser {
 		public ValContext val() {
 			return getRuleContext(ValContext.class,0);
 		}
-		public TerminalNode ID() { return getToken(NCIntentDslParser.ID, 0); }
 		public TerminalNode LPAREN() { return getToken(NCIntentDslParser.LPAREN, 0); }
-		public ExprContext expr() {
-			return getRuleContext(ExprContext.class,0);
+		public List<ExprContext> expr() {
+			return getRuleContexts(ExprContext.class);
+		}
+		public ExprContext expr(int i) {
+			return getRuleContext(ExprContext.class,i);
 		}
 		public TerminalNode RPAREN() { return getToken(NCIntentDslParser.RPAREN, 0); }
+		public TerminalNode ID() { return getToken(NCIntentDslParser.ID, 0); }
+		public MathOpContext mathOp() {
+			return getRuleContext(MathOpContext.class,0);
+		}
 		public ExprContext(ParserRuleContext parent, int invokingState) {
 			super(parent, invokingState);
 		}
@@ -1011,33 +1020,136 @@ public class NCIntentDslParser extends Parser {
 	}
 
 	public final ExprContext expr() throws RecognitionException {
-		ExprContext _localctx = new ExprContext(_ctx, getState());
-		enterRule(_localctx, 28, RULE_expr);
+		return expr(0);
+	}
+
+	private ExprContext expr(int _p) throws RecognitionException {
+		ParserRuleContext _parentctx = _ctx;
+		int _parentState = getState();
+		ExprContext _localctx = new ExprContext(_ctx, _parentState);
+		ExprContext _prevctx = _localctx;
+		int _startState = 28;
+		enterRecursionRule(_localctx, 28, RULE_expr, _p);
+		int _la;
 		try {
-			setState(160);
+			int _alt;
+			enterOuterAlt(_localctx, 1);
+			{
+			setState(168);
 			_errHandler.sync(this);
-			switch ( getInterpreter().adaptivePredict(_input,11,_ctx) ) {
+			switch ( getInterpreter().adaptivePredict(_input,12,_ctx) ) {
 			case 1:
-				enterOuterAlt(_localctx, 1);
 				{
-				setState(154);
+				setState(157);
 				val(0);
 				}
 				break;
 			case 2:
-				enterOuterAlt(_localctx, 2);
 				{
-				setState(155);
+				setState(158);
+				match(LPAREN);
+				setState(159);
+				expr(0);
+				setState(160);
+				match(RPAREN);
+				}
+				break;
+			case 3:
+				{
+				setState(162);
 				match(ID);
-				setState(156);
+				setState(163);
 				match(LPAREN);
-				setState(157);
-				expr();
-				setState(158);
+				setState(165);
+				_errHandler.sync(this);
+				_la = _input.LA(1);
+				if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__4) | (1L << T__6) | (1L << T__7) | (1L << T__8) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << SQSTRING) | (1L << DQSTRING) | (1L << LPAREN) | (1L << TILDA) | (1L << POUND) | (1L << MINUS) | (1L << DOLLAR) | (1L << BOOL) | (1L << INT) | (1L << ID))) != 0)) {
+					{
+					setState(164);
+					expr(0);
+					}
+				}
+
+				setState(167);
 				match(RPAREN);
 				}
 				break;
 			}
+			_ctx.stop = _input.LT(-1);
+			setState(176);
+			_errHandler.sync(this);
+			_alt = getInterpreter().adaptivePredict(_input,13,_ctx);
+			while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
+				if ( _alt==1 ) {
+					if ( _parseListeners!=null ) triggerExitRuleEvent();
+					_prevctx = _localctx;
+					{
+					{
+					_localctx = new ExprContext(_parentctx, _parentState);
+					pushNewRecursionContext(_localctx, _startState, RULE_expr);
+					setState(170);
+					if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)");
+					setState(171);
+					mathOp();
+					setState(172);
+					expr(3);
+					}
+					} 
+				}
+				setState(178);
+				_errHandler.sync(this);
+				_alt = getInterpreter().adaptivePredict(_input,13,_ctx);
+			}
+			}
+		}
+		catch (RecognitionException re) {
+			_localctx.exception = re;
+			_errHandler.reportError(this, re);
+			_errHandler.recover(this, re);
+		}
+		finally {
+			unrollRecursionContexts(_parentctx);
+		}
+		return _localctx;
+	}
+
+	public static class MathOpContext extends ParserRuleContext {
+		public TerminalNode MINUS() { return getToken(NCIntentDslParser.MINUS, 0); }
+		public TerminalNode PLUS() { return getToken(NCIntentDslParser.PLUS, 0); }
+		public TerminalNode STAR() { return getToken(NCIntentDslParser.STAR, 0); }
+		public TerminalNode DEVIDE() { return getToken(NCIntentDslParser.DEVIDE, 0); }
+		public MathOpContext(ParserRuleContext parent, int invokingState) {
+			super(parent, invokingState);
+		}
+		@Override public int getRuleIndex() { return RULE_mathOp; }
+		@Override
+		public void enterRule(ParseTreeListener listener) {
+			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).enterMathOp(this);
+		}
+		@Override
+		public void exitRule(ParseTreeListener listener) {
+			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitMathOp(this);
+		}
+	}
+
+	public final MathOpContext mathOp() throws RecognitionException {
+		MathOpContext _localctx = new MathOpContext(_ctx, getState());
+		enterRule(_localctx, 30, RULE_mathOp);
+		int _la;
+		try {
+			enterOuterAlt(_localctx, 1);
+			{
+			setState(179);
+			_la = _input.LA(1);
+			if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << MINUS) | (1L << PLUS) | (1L << STAR) | (1L << DEVIDE))) != 0)) ) {
+			_errHandler.recoverInline(this);
+			}
+			else {
+				if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
+				_errHandler.reportMatch(this);
+				consume();
+			}
+			}
 		}
 		catch (RecognitionException re) {
 			_localctx.exception = re;
@@ -1086,13 +1198,13 @@ public class NCIntentDslParser extends Parser {
 		int _parentState = getState();
 		ValContext _localctx = new ValContext(_ctx, _parentState);
 		ValContext _prevctx = _localctx;
-		int _startState = 30;
-		enterRecursionRule(_localctx, 30, RULE_val, _p);
+		int _startState = 32;
+		enterRecursionRule(_localctx, 32, RULE_val, _p);
 		try {
 			int _alt;
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(168);
+			setState(187);
 			_errHandler.sync(this);
 			switch (_input.LA(1)) {
 			case T__4:
@@ -1114,17 +1226,17 @@ public class NCIntentDslParser extends Parser {
 			case INT:
 			case ID:
 				{
-				setState(163);
+				setState(182);
 				singleVal();
 				}
 				break;
 			case LPAREN:
 				{
-				setState(164);
+				setState(183);
 				match(LPAREN);
-				setState(165);
+				setState(184);
 				val(0);
-				setState(166);
+				setState(185);
 				match(RPAREN);
 				}
 				break;
@@ -1132,9 +1244,9 @@ public class NCIntentDslParser extends Parser {
 				throw new NoViableAltException(this);
 			}
 			_ctx.stop = _input.LT(-1);
-			setState(175);
+			setState(194);
 			_errHandler.sync(this);
-			_alt = getInterpreter().adaptivePredict(_input,13,_ctx);
+			_alt = getInterpreter().adaptivePredict(_input,15,_ctx);
 			while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
 				if ( _alt==1 ) {
 					if ( _parseListeners!=null ) triggerExitRuleEvent();
@@ -1143,18 +1255,18 @@ public class NCIntentDslParser extends Parser {
 					{
 					_localctx = new ValContext(_parentctx, _parentState);
 					pushNewRecursionContext(_localctx, _startState, RULE_val);
-					setState(170);
+					setState(189);
 					if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)");
-					setState(171);
+					setState(190);
 					match(COMMA);
-					setState(172);
+					setState(191);
 					val(2);
 					}
 					} 
 				}
-				setState(177);
+				setState(196);
 				_errHandler.sync(this);
-				_alt = getInterpreter().adaptivePredict(_input,13,_ctx);
+				_alt = getInterpreter().adaptivePredict(_input,15,_ctx);
 			}
 			}
 		}
@@ -1205,46 +1317,46 @@ public class NCIntentDslParser extends Parser {
 
 	public final SingleValContext singleVal() throws RecognitionException {
 		SingleValContext _localctx = new SingleValContext(_ctx, getState());
-		enterRule(_localctx, 32, RULE_singleVal);
+		enterRule(_localctx, 34, RULE_singleVal);
 		int _la;
 		try {
-			setState(199);
+			setState(218);
 			_errHandler.sync(this);
-			switch ( getInterpreter().adaptivePredict(_input,18,_ctx) ) {
+			switch ( getInterpreter().adaptivePredict(_input,20,_ctx) ) {
 			case 1:
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(178);
+				setState(197);
 				match(T__4);
 				}
 				break;
 			case 2:
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(180);
+				setState(199);
 				_errHandler.sync(this);
 				_la = _input.LA(1);
 				if (_la==MINUS) {
 					{
-					setState(179);
+					setState(198);
 					match(MINUS);
 					}
 				}
 
-				setState(185);
+				setState(204);
 				_errHandler.sync(this);
-				switch ( getInterpreter().adaptivePredict(_input,15,_ctx) ) {
+				switch ( getInterpreter().adaptivePredict(_input,17,_ctx) ) {
 				case 1:
 					{
-					setState(182);
+					setState(201);
 					match(INT);
 					}
 					break;
 				case 2:
 					{
-					setState(183);
+					setState(202);
 					match(INT);
-					setState(184);
+					setState(203);
 					match(EXP);
 					}
 					break;
@@ -1254,31 +1366,31 @@ public class NCIntentDslParser extends Parser {
 			case 3:
 				enterOuterAlt(_localctx, 3);
 				{
-				setState(187);
+				setState(206);
 				match(BOOL);
 				}
 				break;
 			case 4:
 				enterOuterAlt(_localctx, 4);
 				{
-				setState(188);
+				setState(207);
 				qstring();
 				}
 				break;
 			case 5:
 				enterOuterAlt(_localctx, 5);
 				{
-				setState(190);
+				setState(209);
 				_errHandler.sync(this);
 				_la = _input.LA(1);
 				if (_la==ID) {
 					{
-					setState(189);
+					setState(208);
 					tokQual(0);
 					}
 				}
 
-				setState(192);
+				setState(211);
 				_la = _input.LA(1);
 				if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__6) | (1L << T__7) | (1L << T__8) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13))) != 0)) ) {
 				_errHandler.recoverInline(this);
@@ -1293,31 +1405,31 @@ public class NCIntentDslParser extends Parser {
 			case 6:
 				enterOuterAlt(_localctx, 6);
 				{
-				setState(194);
+				setState(213);
 				_errHandler.sync(this);
 				_la = _input.LA(1);
 				if (_la==ID) {
 					{
-					setState(193);
+					setState(212);
 					tokQual(0);
 					}
 				}
 
-				setState(196);
+				setState(215);
 				tokMeta();
 				}
 				break;
 			case 7:
 				enterOuterAlt(_localctx, 7);
 				{
-				setState(197);
+				setState(216);
 				modelMeta();
 				}
 				break;
 			case 8:
 				enterOuterAlt(_localctx, 8);
 				{
-				setState(198);
+				setState(217);
 				intentMeta();
 				}
 				break;
@@ -1364,20 +1476,20 @@ public class NCIntentDslParser extends Parser {
 		int _parentState = getState();
 		TokQualContext _localctx = new TokQualContext(_ctx, _parentState);
 		TokQualContext _prevctx = _localctx;
-		int _startState = 34;
-		enterRecursionRule(_localctx, 34, RULE_tokQual, _p);
+		int _startState = 36;
+		enterRecursionRule(_localctx, 36, RULE_tokQual, _p);
 		try {
 			int _alt;
 			enterOuterAlt(_localctx, 1);
 			{
 			{
-			setState(202);
+			setState(221);
 			tokQualPart();
 			}
 			_ctx.stop = _input.LT(-1);
-			setState(208);
+			setState(227);
 			_errHandler.sync(this);
-			_alt = getInterpreter().adaptivePredict(_input,19,_ctx);
+			_alt = getInterpreter().adaptivePredict(_input,21,_ctx);
 			while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
 				if ( _alt==1 ) {
 					if ( _parseListeners!=null ) triggerExitRuleEvent();
@@ -1386,16 +1498,16 @@ public class NCIntentDslParser extends Parser {
 					{
 					_localctx = new TokQualContext(_parentctx, _parentState);
 					pushNewRecursionContext(_localctx, _startState, RULE_tokQual);
-					setState(204);
+					setState(223);
 					if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)");
-					setState(205);
+					setState(224);
 					tokQualPart();
 					}
 					} 
 				}
-				setState(210);
+				setState(229);
 				_errHandler.sync(this);
-				_alt = getInterpreter().adaptivePredict(_input,19,_ctx);
+				_alt = getInterpreter().adaptivePredict(_input,21,_ctx);
 			}
 			}
 		}
@@ -1429,13 +1541,13 @@ public class NCIntentDslParser extends Parser {
 
 	public final TokQualPartContext tokQualPart() throws RecognitionException {
 		TokQualPartContext _localctx = new TokQualPartContext(_ctx, getState());
-		enterRule(_localctx, 36, RULE_tokQualPart);
+		enterRule(_localctx, 38, RULE_tokQualPart);
 		try {
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(211);
+			setState(230);
 			match(ID);
-			setState(212);
+			setState(231);
 			match(DOT);
 			}
 		}
@@ -1475,47 +1587,47 @@ public class NCIntentDslParser extends Parser {
 
 	public final TokMetaContext tokMeta() throws RecognitionException {
 		TokMetaContext _localctx = new TokMetaContext(_ctx, getState());
-		enterRule(_localctx, 38, RULE_tokMeta);
+		enterRule(_localctx, 40, RULE_tokMeta);
 		try {
-			setState(227);
+			setState(246);
 			_errHandler.sync(this);
-			switch ( getInterpreter().adaptivePredict(_input,20,_ctx) ) {
+			switch ( getInterpreter().adaptivePredict(_input,22,_ctx) ) {
 			case 1:
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(214);
+				setState(233);
 				match(TILDA);
-				setState(215);
+				setState(234);
 				match(ID);
 				}
 				break;
 			case 2:
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(216);
+				setState(235);
 				match(TILDA);
-				setState(217);
+				setState(236);
 				match(ID);
-				setState(218);
+				setState(237);
 				match(LBR);
-				setState(219);
+				setState(238);
 				match(INT);
-				setState(220);
+				setState(239);
 				match(RBR);
 				}
 				break;
 			case 3:
 				enterOuterAlt(_localctx, 3);
 				{
-				setState(221);
+				setState(240);
 				match(TILDA);
-				setState(222);
+				setState(241);
 				match(ID);
-				setState(223);
+				setState(242);
 				match(LBR);
-				setState(224);
+				setState(243);
 				qstring();
-				setState(225);
+				setState(244);
 				match(RBR);
 				}
 				break;
@@ -1557,47 +1669,47 @@ public class NCIntentDslParser extends Parser {
 
 	public final ModelMetaContext modelMeta() throws RecognitionException {
 		ModelMetaContext _localctx = new ModelMetaContext(_ctx, getState());
-		enterRule(_localctx, 40, RULE_modelMeta);
+		enterRule(_localctx, 42, RULE_modelMeta);
 		try {
-			setState(242);
+			setState(261);
 			_errHandler.sync(this);
-			switch ( getInterpreter().adaptivePredict(_input,21,_ctx) ) {
+			switch ( getInterpreter().adaptivePredict(_input,23,_ctx) ) {
 			case 1:
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(229);
+				setState(248);
 				match(POUND);
-				setState(230);
+				setState(249);
 				match(ID);
 				}
 				break;
 			case 2:
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(231);
+				setState(250);
 				match(POUND);
-				setState(232);
+				setState(251);
 				match(ID);
-				setState(233);
+				setState(252);
 				match(LBR);
-				setState(234);
+				setState(253);
 				match(INT);
-				setState(235);
+				setState(254);
 				match(RBR);
 				}
 				break;
 			case 3:
 				enterOuterAlt(_localctx, 3);
 				{
-				setState(236);
+				setState(255);
 				match(POUND);
-				setState(237);
+				setState(256);
 				match(ID);
-				setState(238);
+				setState(257);
 				match(LBR);
-				setState(239);
+				setState(258);
 				qstring();
-				setState(240);
+				setState(259);
 				match(RBR);
 				}
 				break;
@@ -1639,47 +1751,47 @@ public class NCIntentDslParser extends Parser {
 
 	public final IntentMetaContext intentMeta() throws RecognitionException {
 		IntentMetaContext _localctx = new IntentMetaContext(_ctx, getState());
-		enterRule(_localctx, 42, RULE_intentMeta);
+		enterRule(_localctx, 44, RULE_intentMeta);
 		try {
-			setState(257);
+			setState(276);
 			_errHandler.sync(this);
-			switch ( getInterpreter().adaptivePredict(_input,22,_ctx) ) {
+			switch ( getInterpreter().adaptivePredict(_input,24,_ctx) ) {
 			case 1:
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(244);
+				setState(263);
 				match(DOLLAR);
-				setState(245);
+				setState(264);
 				match(ID);
 				}
 				break;
 			case 2:
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(246);
+				setState(265);
 				match(DOLLAR);
-				setState(247);
+				setState(266);
 				match(ID);
-				setState(248);
+				setState(267);
 				match(LBR);
-				setState(249);
+				setState(268);
 				match(INT);
-				setState(250);
+				setState(269);
 				match(RBR);
 				}
 				break;
 			case 3:
 				enterOuterAlt(_localctx, 3);
 				{
-				setState(251);
+				setState(270);
 				match(DOLLAR);
-				setState(252);
+				setState(271);
 				match(ID);
-				setState(253);
+				setState(272);
 				match(LBR);
-				setState(254);
+				setState(273);
 				qstring();
-				setState(255);
+				setState(274);
 				match(RBR);
 				}
 				break;
@@ -1715,12 +1827,12 @@ public class NCIntentDslParser extends Parser {
 
 	public final QstringContext qstring() throws RecognitionException {
 		QstringContext _localctx = new QstringContext(_ctx, getState());
-		enterRule(_localctx, 44, RULE_qstring);
+		enterRule(_localctx, 46, RULE_qstring);
 		int _la;
 		try {
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(259);
+			setState(278);
 			_la = _input.LA(1);
 			if ( !(_la==SQSTRING || _la==DQSTRING) ) {
 			_errHandler.recoverInline(this);
@@ -1766,9 +1878,9 @@ public class NCIntentDslParser extends Parser {
 
 	public final MinMaxContext minMax() throws RecognitionException {
 		MinMaxContext _localctx = new MinMaxContext(_ctx, getState());
-		enterRule(_localctx, 46, RULE_minMax);
+		enterRule(_localctx, 48, RULE_minMax);
 		try {
-			setState(263);
+			setState(282);
 			_errHandler.sync(this);
 			switch (_input.LA(1)) {
 			case PLUS:
@@ -1776,14 +1888,14 @@ public class NCIntentDslParser extends Parser {
 			case STAR:
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(261);
+				setState(280);
 				minMaxShortcut();
 				}
 				break;
 			case LBR:
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(262);
+				setState(281);
 				minMaxRange();
 				}
 				break;
@@ -1822,12 +1934,12 @@ public class NCIntentDslParser extends Parser {
 
 	public final MinMaxShortcutContext minMaxShortcut() throws RecognitionException {
 		MinMaxShortcutContext _localctx = new MinMaxShortcutContext(_ctx, getState());
-		enterRule(_localctx, 48, RULE_minMaxShortcut);
+		enterRule(_localctx, 50, RULE_minMaxShortcut);
 		int _la;
 		try {
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(265);
+			setState(284);
 			_la = _input.LA(1);
 			if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << PLUS) | (1L << QUESTION) | (1L << STAR))) != 0)) ) {
 			_errHandler.recoverInline(this);
@@ -1874,19 +1986,19 @@ public class NCIntentDslParser extends Parser {
 
 	public final MinMaxRangeContext minMaxRange() throws RecognitionException {
 		MinMaxRangeContext _localctx = new MinMaxRangeContext(_ctx, getState());
-		enterRule(_localctx, 50, RULE_minMaxRange);
+		enterRule(_localctx, 52, RULE_minMaxRange);
 		try {
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(267);
+			setState(286);
 			match(LBR);
-			setState(268);
+			setState(287);
 			match(INT);
-			setState(269);
+			setState(288);
 			match(COMMA);
-			setState(270);
+			setState(289);
 			match(INT);
-			setState(271);
+			setState(290);
 			match(RBR);
 			}
 		}
@@ -1909,9 +2021,11 @@ public class NCIntentDslParser extends Parser {
 			return terms_sempred((TermsContext)_localctx, predIndex);
 		case 12:
 			return item_sempred((ItemContext)_localctx, predIndex);
-		case 15:
+		case 14:
+			return expr_sempred((ExprContext)_localctx, predIndex);
+		case 16:
 			return val_sempred((ValContext)_localctx, predIndex);
-		case 17:
+		case 18:
 			return tokQual_sempred((TokQualContext)_localctx, predIndex);
 		}
 		return true;
@@ -1937,113 +2051,129 @@ public class NCIntentDslParser extends Parser {
 		}
 		return true;
 	}
-	private boolean val_sempred(ValContext _localctx, int predIndex) {
+	private boolean expr_sempred(ExprContext _localctx, int predIndex) {
 		switch (predIndex) {
 		case 3:
+			return precpred(_ctx, 2);
+		}
+		return true;
+	}
+	private boolean val_sempred(ValContext _localctx, int predIndex) {
+		switch (predIndex) {
+		case 4:
 			return precpred(_ctx, 1);
 		}
 		return true;
 	}
 	private boolean tokQual_sempred(TokQualContext _localctx, int predIndex) {
 		switch (predIndex) {
-		case 4:
+		case 5:
 			return precpred(_ctx, 1);
 		}
 		return true;
 	}
 
 	public static final String _serializedATN =
-		"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\63\u0114\4\2\t\2"+
+		"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\64\u0127\4\2\t\2"+
 		"\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+
 		"\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+
 		"\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+
-		"\4\32\t\32\4\33\t\33\3\2\3\2\5\29\n\2\3\2\5\2<\n\2\3\2\5\2?\n\2\3\2\3"+
-		"\2\3\2\3\3\3\3\3\3\3\3\3\4\3\4\3\4\3\4\3\5\3\5\3\5\3\5\3\6\3\6\3\6\3\6"+
-		"\5\6T\n\6\3\6\3\6\3\7\3\7\3\7\3\7\3\7\3\7\7\7^\n\7\f\7\16\7a\13\7\3\b"+
-		"\3\b\3\b\3\b\3\t\3\t\3\t\5\tj\n\t\3\n\3\n\3\n\3\n\3\n\7\nq\n\n\f\n\16"+
-		"\nt\13\n\3\13\3\13\3\f\3\f\5\fz\n\f\3\f\3\f\3\f\3\f\3\f\5\f\u0081\n\f"+
-		"\3\r\3\r\3\r\3\r\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\16\5\16\u008f\n"+
-		"\16\3\16\3\16\3\16\7\16\u0094\n\16\f\16\16\16\u0097\13\16\3\17\3\17\3"+
-		"\17\3\17\3\20\3\20\3\20\3\20\3\20\3\20\5\20\u00a3\n\20\3\21\3\21\3\21"+
-		"\3\21\3\21\3\21\5\21\u00ab\n\21\3\21\3\21\3\21\7\21\u00b0\n\21\f\21\16"+
-		"\21\u00b3\13\21\3\22\3\22\5\22\u00b7\n\22\3\22\3\22\3\22\5\22\u00bc\n"+
-		"\22\3\22\3\22\3\22\5\22\u00c1\n\22\3\22\3\22\5\22\u00c5\n\22\3\22\3\22"+
-		"\3\22\5\22\u00ca\n\22\3\23\3\23\3\23\3\23\3\23\7\23\u00d1\n\23\f\23\16"+
-		"\23\u00d4\13\23\3\24\3\24\3\24\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25"+
-		"\3\25\3\25\3\25\3\25\3\25\5\25\u00e6\n\25\3\26\3\26\3\26\3\26\3\26\3\26"+
-		"\3\26\3\26\3\26\3\26\3\26\3\26\3\26\5\26\u00f5\n\26\3\27\3\27\3\27\3\27"+
-		"\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\5\27\u0104\n\27\3\30\3\30"+
-		"\3\31\3\31\5\31\u010a\n\31\3\32\3\32\3\33\3\33\3\33\3\33\3\33\3\33\3\33"+
-		"\2\7\f\22\32 $\34\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60\62"+
-		"\64\2\7\4\2\36\36((\3\2\24\25\3\2\t\20\3\2\21\22\3\2)+\2\u011c\2\66\3"+
-		"\2\2\2\4C\3\2\2\2\6G\3\2\2\2\bK\3\2\2\2\nO\3\2\2\2\fW\3\2\2\2\16b\3\2"+
-		"\2\2\20i\3\2\2\2\22k\3\2\2\2\24u\3\2\2\2\26w\3\2\2\2\30\u0082\3\2\2\2"+
-		"\32\u008e\3\2\2\2\34\u0098\3\2\2\2\36\u00a2\3\2\2\2 \u00aa\3\2\2\2\"\u00c9"+
-		"\3\2\2\2$\u00cb\3\2\2\2&\u00d5\3\2\2\2(\u00e5\3\2\2\2*\u00f4\3\2\2\2,"+
-		"\u0103\3\2\2\2.\u0105\3\2\2\2\60\u0109\3\2\2\2\62\u010b\3\2\2\2\64\u010d"+
-		"\3\2\2\2\668\5\4\3\2\679\5\6\4\28\67\3\2\2\289\3\2\2\29;\3\2\2\2:<\5\b"+
-		"\5\2;:\3\2\2\2;<\3\2\2\2<>\3\2\2\2=?\5\n\6\2>=\3\2\2\2>?\3\2\2\2?@\3\2"+
-		"\2\2@A\5\22\n\2AB\7\2\2\3B\3\3\2\2\2CD\7\3\2\2DE\7(\2\2EF\7\61\2\2F\5"+
-		"\3\2\2\2GH\7\4\2\2HI\7(\2\2IJ\7.\2\2J\7\3\2\2\2KL\7\5\2\2LM\7(\2\2MN\5"+
-		".\30\2N\t\3\2\2\2OP\7\6\2\2PQ\7(\2\2QS\7\32\2\2RT\5\f\7\2SR\3\2\2\2ST"+
-		"\3\2\2\2TU\3\2\2\2UV\7\33\2\2V\13\3\2\2\2WX\b\7\1\2XY\5\16\b\2Y_\3\2\2"+
-		"\2Z[\f\3\2\2[\\\7#\2\2\\^\5\16\b\2]Z\3\2\2\2^a\3\2\2\2_]\3\2\2\2_`\3\2"+
-		"\2\2`\r\3\2\2\2a_\3\2\2\2bc\5.\30\2cd\7$\2\2de\5\20\t\2e\17\3\2\2\2fj"+
-		"\7\7\2\2gj\7.\2\2hj\5.\30\2if\3\2\2\2ig\3\2\2\2ih\3\2\2\2j\21\3\2\2\2"+
-		"kl\b\n\1\2lm\5\26\f\2mr\3\2\2\2no\f\3\2\2oq\5\26\f\2pn\3\2\2\2qt\3\2\2"+
-		"\2rp\3\2\2\2rs\3\2\2\2s\23\3\2\2\2tr\3\2\2\2uv\t\2\2\2v\25\3\2\2\2wy\7"+
-		"\b\2\2xz\5\30\r\2yx\3\2\2\2yz\3\2\2\2z{\3\2\2\2{|\5\24\13\2|}\7\32\2\2"+
-		"}~\5\32\16\2~\u0080\7\33\2\2\177\u0081\5\60\31\2\u0080\177\3\2\2\2\u0080"+
-		"\u0081\3\2\2\2\u0081\27\3\2\2\2\u0082\u0083\7\30\2\2\u0083\u0084\7\61"+
-		"\2\2\u0084\u0085\7\31\2\2\u0085\31\3\2\2\2\u0086\u0087\b\16\1\2\u0087"+
-		"\u008f\5\34\17\2\u0088\u0089\7\30\2\2\u0089\u008a\5\32\16\2\u008a\u008b"+
-		"\7\31\2\2\u008b\u008f\3\2\2\2\u008c\u008d\7\27\2\2\u008d\u008f\5\32\16"+
-		"\3\u008e\u0086\3\2\2\2\u008e\u0088\3\2\2\2\u008e\u008c\3\2\2\2\u008f\u0095"+
-		"\3\2\2\2\u0090\u0091\f\4\2\2\u0091\u0092\t\3\2\2\u0092\u0094\5\32\16\5"+
-		"\u0093\u0090\3\2\2\2\u0094\u0097\3\2\2\2\u0095\u0093\3\2\2\2\u0095\u0096"+
-		"\3\2\2\2\u0096\33\3\2\2\2\u0097\u0095\3\2\2\2\u0098\u0099\5\36\20\2\u0099"+
-		"\u009a\7\23\2\2\u009a\u009b\5\36\20\2\u009b\35\3\2\2\2\u009c\u00a3\5 "+
-		"\21\2\u009d\u009e\7\61\2\2\u009e\u009f\7\30\2\2\u009f\u00a0\5\36\20\2"+
-		"\u00a0\u00a1\7\31\2\2\u00a1\u00a3\3\2\2\2\u00a2\u009c\3\2\2\2\u00a2\u009d"+
-		"\3\2\2\2\u00a3\37\3\2\2\2\u00a4\u00a5\b\21\1\2\u00a5\u00ab\5\"\22\2\u00a6"+
-		"\u00a7\7\30\2\2\u00a7\u00a8\5 \21\2\u00a8\u00a9\7\31\2\2\u00a9\u00ab\3"+
-		"\2\2\2\u00aa\u00a4\3\2\2\2\u00aa\u00a6\3\2\2\2\u00ab\u00b1\3\2\2\2\u00ac"+
-		"\u00ad\f\3\2\2\u00ad\u00ae\7#\2\2\u00ae\u00b0\5 \21\4\u00af\u00ac\3\2"+
-		"\2\2\u00b0\u00b3\3\2\2\2\u00b1\u00af\3\2\2\2\u00b1\u00b2\3\2\2\2\u00b2"+
-		"!\3\2\2\2\u00b3\u00b1\3\2\2\2\u00b4\u00ca\7\7\2\2\u00b5\u00b7\7%\2\2\u00b6"+
-		"\u00b5\3\2\2\2\u00b6\u00b7\3\2\2\2\u00b7\u00bb\3\2\2\2\u00b8\u00bc\7/"+
-		"\2\2\u00b9\u00ba\7/\2\2\u00ba\u00bc\7\60\2\2\u00bb\u00b8\3\2\2\2\u00bb"+
-		"\u00b9\3\2\2\2\u00bc\u00ca\3\2\2\2\u00bd\u00ca\7.\2\2\u00be\u00ca\5.\30"+
-		"\2\u00bf\u00c1\5$\23\2\u00c0\u00bf\3\2\2\2\u00c0\u00c1\3\2\2\2\u00c1\u00c2"+
-		"\3\2\2\2\u00c2\u00ca\t\4\2\2\u00c3\u00c5\5$\23\2\u00c4\u00c3\3\2\2\2\u00c4"+
-		"\u00c5\3\2\2\2\u00c5\u00c6\3\2\2\2\u00c6\u00ca\5(\25\2\u00c7\u00ca\5*"+
-		"\26\2\u00c8\u00ca\5,\27\2\u00c9\u00b4\3\2\2\2\u00c9\u00b6\3\2\2\2\u00c9"+
-		"\u00bd\3\2\2\2\u00c9\u00be\3\2\2\2\u00c9\u00c0\3\2\2\2\u00c9\u00c4\3\2"+
-		"\2\2\u00c9\u00c7\3\2\2\2\u00c9\u00c8\3\2\2\2\u00ca#\3\2\2\2\u00cb\u00cc"+
-		"\b\23\1\2\u00cc\u00cd\5&\24\2\u00cd\u00d2\3\2\2\2\u00ce\u00cf\f\3\2\2"+
-		"\u00cf\u00d1\5&\24\2\u00d0\u00ce\3\2\2\2\u00d1\u00d4\3\2\2\2\u00d2\u00d0"+
-		"\3\2\2\2\u00d2\u00d3\3\2\2\2\u00d3%\3\2\2\2\u00d4\u00d2\3\2\2\2\u00d5"+
-		"\u00d6\7\61\2\2\u00d6\u00d7\7&\2\2\u00d7\'\3\2\2\2\u00d8\u00d9\7\36\2"+
-		"\2\u00d9\u00e6\7\61\2\2\u00da\u00db\7\36\2\2\u00db\u00dc\7\61\2\2\u00dc"+
-		"\u00dd\7 \2\2\u00dd\u00de\7/\2\2\u00de\u00e6\7!\2\2\u00df\u00e0\7\36\2"+
-		"\2\u00e0\u00e1\7\61\2\2\u00e1\u00e2\7 \2\2\u00e2\u00e3\5.\30\2\u00e3\u00e4"+
-		"\7!\2\2\u00e4\u00e6\3\2\2\2\u00e5\u00d8\3\2\2\2\u00e5\u00da\3\2\2\2\u00e5"+
-		"\u00df\3\2\2\2\u00e6)\3\2\2\2\u00e7\u00e8\7\"\2\2\u00e8\u00f5\7\61\2\2"+
-		"\u00e9\u00ea\7\"\2\2\u00ea\u00eb\7\61\2\2\u00eb\u00ec\7 \2\2\u00ec\u00ed"+
-		"\7/\2\2\u00ed\u00f5\7!\2\2\u00ee\u00ef\7\"\2\2\u00ef\u00f0\7\61\2\2\u00f0"+
-		"\u00f1\7 \2\2\u00f1\u00f2\5.\30\2\u00f2\u00f3\7!\2\2\u00f3\u00f5\3\2\2"+
-		"\2\u00f4\u00e7\3\2\2\2\u00f4\u00e9\3\2\2\2\u00f4\u00ee\3\2\2\2\u00f5+"+
-		"\3\2\2\2\u00f6\u00f7\7,\2\2\u00f7\u0104\7\61\2\2\u00f8\u00f9\7,\2\2\u00f9"+
-		"\u00fa\7\61\2\2\u00fa\u00fb\7 \2\2\u00fb\u00fc\7/\2\2\u00fc\u0104\7!\2"+
-		"\2\u00fd\u00fe\7,\2\2\u00fe\u00ff\7\61\2\2\u00ff\u0100\7 \2\2\u0100\u0101"+
-		"\5.\30\2\u0101\u0102\7!\2\2\u0102\u0104\3\2\2\2\u0103\u00f6\3\2\2\2\u0103"+
-		"\u00f8\3\2\2\2\u0103\u00fd\3\2\2\2\u0104-\3\2\2\2\u0105\u0106\t\5\2\2"+
-		"\u0106/\3\2\2\2\u0107\u010a\5\62\32\2\u0108\u010a\5\64\33\2\u0109\u0107"+
-		"\3\2\2\2\u0109\u0108\3\2\2\2\u010a\61\3\2\2\2\u010b\u010c\t\6\2\2\u010c"+
-		"\63\3\2\2\2\u010d\u010e\7 \2\2\u010e\u010f\7/\2\2\u010f\u0110\7#\2\2\u0110"+
-		"\u0111\7/\2\2\u0111\u0112\7!\2\2\u0112\65\3\2\2\2\328;>S_iry\u0080\u008e"+
-		"\u0095\u00a2\u00aa\u00b1\u00b6\u00bb\u00c0\u00c4\u00c9\u00d2\u00e5\u00f4"+
-		"\u0103\u0109";
+		"\4\32\t\32\4\33\t\33\4\34\t\34\3\2\3\2\5\2;\n\2\3\2\5\2>\n\2\3\2\5\2A"+
+		"\n\2\3\2\3\2\3\2\3\3\3\3\3\3\3\3\3\4\3\4\3\4\3\4\3\5\3\5\3\5\3\5\3\6\3"+
+		"\6\3\6\3\6\5\6V\n\6\3\6\3\6\3\7\3\7\3\7\3\7\3\7\3\7\7\7`\n\7\f\7\16\7"+
+		"c\13\7\3\b\3\b\3\b\3\b\3\t\3\t\3\t\5\tl\n\t\3\n\3\n\3\n\3\n\3\n\7\ns\n"+
+		"\n\f\n\16\nv\13\n\3\13\3\13\3\f\3\f\5\f|\n\f\3\f\3\f\3\f\3\f\3\f\5\f\u0083"+
+		"\n\f\3\r\3\r\3\r\3\r\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\16\5\16\u0091"+
+		"\n\16\3\16\3\16\3\16\7\16\u0096\n\16\f\16\16\16\u0099\13\16\3\17\3\17"+
+		"\3\17\3\17\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\5\20\u00a8\n\20"+
+		"\3\20\5\20\u00ab\n\20\3\20\3\20\3\20\3\20\7\20\u00b1\n\20\f\20\16\20\u00b4"+
+		"\13\20\3\21\3\21\3\22\3\22\3\22\3\22\3\22\3\22\5\22\u00be\n\22\3\22\3"+
+		"\22\3\22\7\22\u00c3\n\22\f\22\16\22\u00c6\13\22\3\23\3\23\5\23\u00ca\n"+
+		"\23\3\23\3\23\3\23\5\23\u00cf\n\23\3\23\3\23\3\23\5\23\u00d4\n\23\3\23"+
+		"\3\23\5\23\u00d8\n\23\3\23\3\23\3\23\5\23\u00dd\n\23\3\24\3\24\3\24\3"+
+		"\24\3\24\7\24\u00e4\n\24\f\24\16\24\u00e7\13\24\3\25\3\25\3\25\3\26\3"+
+		"\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\5\26\u00f9"+
+		"\n\26\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27"+
+		"\5\27\u0108\n\27\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30"+
+		"\3\30\3\30\5\30\u0117\n\30\3\31\3\31\3\32\3\32\5\32\u011d\n\32\3\33\3"+
+		"\33\3\34\3\34\3\34\3\34\3\34\3\34\3\34\2\b\f\22\32\36\"&\35\2\4\6\b\n"+
+		"\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60\62\64\66\2\b\4\2\36\36((\3\2"+
+		"\24\25\5\2%%))+,\3\2\t\20\3\2\21\22\3\2)+\2\u0131\28\3\2\2\2\4E\3\2\2"+
+		"\2\6I\3\2\2\2\bM\3\2\2\2\nQ\3\2\2\2\fY\3\2\2\2\16d\3\2\2\2\20k\3\2\2\2"+
+		"\22m\3\2\2\2\24w\3\2\2\2\26y\3\2\2\2\30\u0084\3\2\2\2\32\u0090\3\2\2\2"+
+		"\34\u009a\3\2\2\2\36\u00aa\3\2\2\2 \u00b5\3\2\2\2\"\u00bd\3\2\2\2$\u00dc"+
+		"\3\2\2\2&\u00de\3\2\2\2(\u00e8\3\2\2\2*\u00f8\3\2\2\2,\u0107\3\2\2\2."+
+		"\u0116\3\2\2\2\60\u0118\3\2\2\2\62\u011c\3\2\2\2\64\u011e\3\2\2\2\66\u0120"+
+		"\3\2\2\28:\5\4\3\29;\5\6\4\2:9\3\2\2\2:;\3\2\2\2;=\3\2\2\2<>\5\b\5\2="+
+		"<\3\2\2\2=>\3\2\2\2>@\3\2\2\2?A\5\n\6\2@?\3\2\2\2@A\3\2\2\2AB\3\2\2\2"+
+		"BC\5\22\n\2CD\7\2\2\3D\3\3\2\2\2EF\7\3\2\2FG\7(\2\2GH\7\62\2\2H\5\3\2"+
+		"\2\2IJ\7\4\2\2JK\7(\2\2KL\7/\2\2L\7\3\2\2\2MN\7\5\2\2NO\7(\2\2OP\5\60"+
+		"\31\2P\t\3\2\2\2QR\7\6\2\2RS\7(\2\2SU\7\32\2\2TV\5\f\7\2UT\3\2\2\2UV\3"+
+		"\2\2\2VW\3\2\2\2WX\7\33\2\2X\13\3\2\2\2YZ\b\7\1\2Z[\5\16\b\2[a\3\2\2\2"+
+		"\\]\f\3\2\2]^\7#\2\2^`\5\16\b\2_\\\3\2\2\2`c\3\2\2\2a_\3\2\2\2ab\3\2\2"+
+		"\2b\r\3\2\2\2ca\3\2\2\2de\5\60\31\2ef\7$\2\2fg\5\20\t\2g\17\3\2\2\2hl"+
+		"\7\7\2\2il\7/\2\2jl\5\60\31\2kh\3\2\2\2ki\3\2\2\2kj\3\2\2\2l\21\3\2\2"+
+		"\2mn\b\n\1\2no\5\26\f\2ot\3\2\2\2pq\f\3\2\2qs\5\26\f\2rp\3\2\2\2sv\3\2"+
+		"\2\2tr\3\2\2\2tu\3\2\2\2u\23\3\2\2\2vt\3\2\2\2wx\t\2\2\2x\25\3\2\2\2y"+
+		"{\7\b\2\2z|\5\30\r\2{z\3\2\2\2{|\3\2\2\2|}\3\2\2\2}~\5\24\13\2~\177\7"+
+		"\32\2\2\177\u0080\5\32\16\2\u0080\u0082\7\33\2\2\u0081\u0083\5\62\32\2"+
+		"\u0082\u0081\3\2\2\2\u0082\u0083\3\2\2\2\u0083\27\3\2\2\2\u0084\u0085"+
+		"\7\30\2\2\u0085\u0086\7\62\2\2\u0086\u0087\7\31\2\2\u0087\31\3\2\2\2\u0088"+
+		"\u0089\b\16\1\2\u0089\u0091\5\34\17\2\u008a\u008b\7\30\2\2\u008b\u008c"+
+		"\5\32\16\2\u008c\u008d\7\31\2\2\u008d\u0091\3\2\2\2\u008e\u008f\7\27\2"+
+		"\2\u008f\u0091\5\32\16\3\u0090\u0088\3\2\2\2\u0090\u008a\3\2\2\2\u0090"+
+		"\u008e\3\2\2\2\u0091\u0097\3\2\2\2\u0092\u0093\f\4\2\2\u0093\u0094\t\3"+
+		"\2\2\u0094\u0096\5\32\16\5\u0095\u0092\3\2\2\2\u0096\u0099\3\2\2\2\u0097"+
+		"\u0095\3\2\2\2\u0097\u0098\3\2\2\2\u0098\33\3\2\2\2\u0099\u0097\3\2\2"+
+		"\2\u009a\u009b\5\36\20\2\u009b\u009c\7\23\2\2\u009c\u009d\5\36\20\2\u009d"+
+		"\35\3\2\2\2\u009e\u009f\b\20\1\2\u009f\u00ab\5\"\22\2\u00a0\u00a1\7\30"+
+		"\2\2\u00a1\u00a2\5\36\20\2\u00a2\u00a3\7\31\2\2\u00a3\u00ab\3\2\2\2\u00a4"+
+		"\u00a5\7\62\2\2\u00a5\u00a7\7\30\2\2\u00a6\u00a8\5\36\20\2\u00a7\u00a6"+
+		"\3\2\2\2\u00a7\u00a8\3\2\2\2\u00a8\u00a9\3\2\2\2\u00a9\u00ab\7\31\2\2"+
+		"\u00aa\u009e\3\2\2\2\u00aa\u00a0\3\2\2\2\u00aa\u00a4\3\2\2\2\u00ab\u00b2"+
+		"\3\2\2\2\u00ac\u00ad\f\4\2\2\u00ad\u00ae\5 \21\2\u00ae\u00af\5\36\20\5"+
+		"\u00af\u00b1\3\2\2\2\u00b0\u00ac\3\2\2\2\u00b1\u00b4\3\2\2\2\u00b2\u00b0"+
+		"\3\2\2\2\u00b2\u00b3\3\2\2\2\u00b3\37\3\2\2\2\u00b4\u00b2\3\2\2\2\u00b5"+
+		"\u00b6\t\4\2\2\u00b6!\3\2\2\2\u00b7\u00b8\b\22\1\2\u00b8\u00be\5$\23\2"+
+		"\u00b9\u00ba\7\30\2\2\u00ba\u00bb\5\"\22\2\u00bb\u00bc\7\31\2\2\u00bc"+
+		"\u00be\3\2\2\2\u00bd\u00b7\3\2\2\2\u00bd\u00b9\3\2\2\2\u00be\u00c4\3\2"+
+		"\2\2\u00bf\u00c0\f\3\2\2\u00c0\u00c1\7#\2\2\u00c1\u00c3\5\"\22\4\u00c2"+
+		"\u00bf\3\2\2\2\u00c3\u00c6\3\2\2\2\u00c4\u00c2\3\2\2\2\u00c4\u00c5\3\2"+
+		"\2\2\u00c5#\3\2\2\2\u00c6\u00c4\3\2\2\2\u00c7\u00dd\7\7\2\2\u00c8\u00ca"+
+		"\7%\2\2\u00c9\u00c8\3\2\2\2\u00c9\u00ca\3\2\2\2\u00ca\u00ce\3\2\2\2\u00cb"+
+		"\u00cf\7\60\2\2\u00cc\u00cd\7\60\2\2\u00cd\u00cf\7\61\2\2\u00ce\u00cb"+
+		"\3\2\2\2\u00ce\u00cc\3\2\2\2\u00cf\u00dd\3\2\2\2\u00d0\u00dd\7/\2\2\u00d1"+
+		"\u00dd\5\60\31\2\u00d2\u00d4\5&\24\2\u00d3\u00d2\3\2\2\2\u00d3\u00d4\3"+
+		"\2\2\2\u00d4\u00d5\3\2\2\2\u00d5\u00dd\t\5\2\2\u00d6\u00d8\5&\24\2\u00d7"+
+		"\u00d6\3\2\2\2\u00d7\u00d8\3\2\2\2\u00d8\u00d9\3\2\2\2\u00d9\u00dd\5*"+
+		"\26\2\u00da\u00dd\5,\27\2\u00db\u00dd\5.\30\2\u00dc\u00c7\3\2\2\2\u00dc"+
+		"\u00c9\3\2\2\2\u00dc\u00d0\3\2\2\2\u00dc\u00d1\3\2\2\2\u00dc\u00d3\3\2"+
+		"\2\2\u00dc\u00d7\3\2\2\2\u00dc\u00da\3\2\2\2\u00dc\u00db\3\2\2\2\u00dd"+
+		"%\3\2\2\2\u00de\u00df\b\24\1\2\u00df\u00e0\5(\25\2\u00e0\u00e5\3\2\2\2"+
+		"\u00e1\u00e2\f\3\2\2\u00e2\u00e4\5(\25\2\u00e3\u00e1\3\2\2\2\u00e4\u00e7"+
+		"\3\2\2\2\u00e5\u00e3\3\2\2\2\u00e5\u00e6\3\2\2\2\u00e6\'\3\2\2\2\u00e7"+
+		"\u00e5\3\2\2\2\u00e8\u00e9\7\62\2\2\u00e9\u00ea\7&\2\2\u00ea)\3\2\2\2"+
+		"\u00eb\u00ec\7\36\2\2\u00ec\u00f9\7\62\2\2\u00ed\u00ee\7\36\2\2\u00ee"+
+		"\u00ef\7\62\2\2\u00ef\u00f0\7 \2\2\u00f0\u00f1\7\60\2\2\u00f1\u00f9\7"+
+		"!\2\2\u00f2\u00f3\7\36\2\2\u00f3\u00f4\7\62\2\2\u00f4\u00f5\7 \2\2\u00f5"+
+		"\u00f6\5\60\31\2\u00f6\u00f7\7!\2\2\u00f7\u00f9\3\2\2\2\u00f8\u00eb\3"+
+		"\2\2\2\u00f8\u00ed\3\2\2\2\u00f8\u00f2\3\2\2\2\u00f9+\3\2\2\2\u00fa\u00fb"+
+		"\7\"\2\2\u00fb\u0108\7\62\2\2\u00fc\u00fd\7\"\2\2\u00fd\u00fe\7\62\2\2"+
+		"\u00fe\u00ff\7 \2\2\u00ff\u0100\7\60\2\2\u0100\u0108\7!\2\2\u0101\u0102"+
+		"\7\"\2\2\u0102\u0103\7\62\2\2\u0103\u0104\7 \2\2\u0104\u0105\5\60\31\2"+
+		"\u0105\u0106\7!\2\2\u0106\u0108\3\2\2\2\u0107\u00fa\3\2\2\2\u0107\u00fc"+
+		"\3\2\2\2\u0107\u0101\3\2\2\2\u0108-\3\2\2\2\u0109\u010a\7-\2\2\u010a\u0117"+
+		"\7\62\2\2\u010b\u010c\7-\2\2\u010c\u010d\7\62\2\2\u010d\u010e\7 \2\2\u010e"+
+		"\u010f\7\60\2\2\u010f\u0117\7!\2\2\u0110\u0111\7-\2\2\u0111\u0112\7\62"+
+		"\2\2\u0112\u0113\7 \2\2\u0113\u0114\5\60\31\2\u0114\u0115\7!\2\2\u0115"+
+		"\u0117\3\2\2\2\u0116\u0109\3\2\2\2\u0116\u010b\3\2\2\2\u0116\u0110\3\2"+
+		"\2\2\u0117/\3\2\2\2\u0118\u0119\t\6\2\2\u0119\61\3\2\2\2\u011a\u011d\5"+
+		"\64\33\2\u011b\u011d\5\66\34\2\u011c\u011a\3\2\2\2\u011c\u011b\3\2\2\2"+
+		"\u011d\63\3\2\2\2\u011e\u011f\t\7\2\2\u011f\65\3\2\2\2\u0120\u0121\7 "+
+		"\2\2\u0121\u0122\7\60\2\2\u0122\u0123\7#\2\2\u0123\u0124\7\60\2\2\u0124"+
+		"\u0125\7!\2\2\u0125\67\3\2\2\2\34:=@Uakt{\u0082\u0090\u0097\u00a7\u00aa"+
+		"\u00b2\u00bd\u00c4\u00c9\u00ce\u00d3\u00d7\u00dc\u00e5\u00f8\u0107\u0116"+
+		"\u011c";
 	public static final ATN _ATN =
 		new ATNDeserializer().deserialize(_serializedATN.toCharArray());
 	static {
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDsl.g4 b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDsl.g4
index bb7ee64..aae4ee5 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDsl.g4
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDsl.g4
@@ -31,7 +31,15 @@ item
 pred: expr PRED_OP expr;
 expr
     : val
-    | ID LPAREN expr RPAREN // Buit-in function call.
+    | LPAREN expr RPAREN
+    | expr mathOp expr
+    | ID LPAREN expr? RPAREN // Buit-in function call.
+    ;
+mathOp
+    : MINUS
+    | PLUS
+    | STAR
+    | DEVIDE
     ;
 val
     : singleVal
@@ -95,6 +103,9 @@ DOLLAR: '$';
 TILDA: '~';
 LBR: '[';
 RBR: ']';
+PLUS: '+';
+STAR: '*';
+DEVIDE: '/';
 COMMA: ',';
 COLON: ':';
 POUND: '#';
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDsl.interp b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDsl.interp
index 0aa2601..0dca965 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDsl.interp
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDsl.interp
@@ -23,6 +23,9 @@ null
 '~'
 '['
 ']'
+'+'
+'*'
+'/'
 ','
 ':'
 '#'
@@ -61,6 +64,9 @@ DOLLAR
 TILDA
 LBR
 RBR
+PLUS
+STAR
+DEVIDE
 COMMA
 COLON
 POUND
@@ -80,6 +86,7 @@ alias
 item
 pred
 expr
+mathOp
 val
 singleVal
 tokQual
@@ -91,4 +98,4 @@ qstring
 
 
 atn:
-[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 37, 173, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 5, 2, 38, 10, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 5, 4, 52, 10, 4, 3, 4, 3, 4, 3, 4, 7, 4, 57, 10, 4, 12, 4, 14, 4, 60, 11, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 6, 3, 6 [...]
\ No newline at end of file
+[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 40, 192, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 5, 2, 40, 10, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 5, 4, 54, 10, 4, 3, 4, 3, 4, 3, 4, 7, 4, 59, 10, 4, 12, 4, 14, 4, 62, 11, 4, 3, 5, 3, 5, 3, 5, 3, [...]
\ No newline at end of file
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDsl.tokens b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDsl.tokens
index 7d51b56..041c397 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDsl.tokens
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDsl.tokens
@@ -21,18 +21,21 @@ DOLLAR=20
 TILDA=21
 LBR=22
 RBR=23
-COMMA=24
-COLON=25
-POUND=26
-MINUS=27
-DOT=28
-UNDERSCORE=29
-BOOL=30
-INT=31
-EXP=32
-ID=33
-WS=34
-ErrorCharacter=35
+PLUS=24
+STAR=25
+DEVIDE=26
+COMMA=27
+COLON=28
+POUND=29
+MINUS=30
+DOT=31
+UNDERSCORE=32
+BOOL=33
+INT=34
+EXP=35
+ID=36
+WS=37
+ErrorCharacter=38
 'null'=1
 'id'=2
 'aliases'=3
@@ -53,9 +56,12 @@ ErrorCharacter=35
 '~'=21
 '['=22
 ']'=23
-','=24
-':'=25
-'#'=26
-'-'=27
-'.'=28
-'_'=29
+'+'=24
+'*'=25
+'/'=26
+','=27
+':'=28
+'#'=29
+'-'=30
+'.'=31
+'_'=32
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDslBaseListener.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDslBaseListener.java
index 6258388..26791e8 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDslBaseListener.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDslBaseListener.java
@@ -76,6 +76,18 @@ public class NCSynonymDslBaseListener implements NCSynonymDslListener {
 	 *
 	 * <p>The default implementation does nothing.</p>
 	 */
+	@Override public void enterMathOp(NCSynonymDslParser.MathOpContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
+	@Override public void exitMathOp(NCSynonymDslParser.MathOpContext ctx) { }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation does nothing.</p>
+	 */
 	@Override public void enterVal(NCSynonymDslParser.ValContext ctx) { }
 	/**
 	 * {@inheritDoc}
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDslLexer.interp b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDslLexer.interp
index b2c4a40..d3cec1e 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDslLexer.interp
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDslLexer.interp
@@ -23,6 +23,9 @@ null
 '~'
 '['
 ']'
+'+'
+'*'
+'/'
 ','
 ':'
 '#'
@@ -61,6 +64,9 @@ DOLLAR
 TILDA
 LBR
 RBR
+PLUS
+STAR
+DEVIDE
 COMMA
 COLON
 POUND
@@ -98,6 +104,9 @@ DOLLAR
 TILDA
 LBR
 RBR
+PLUS
+STAR
+DEVIDE
 COMMA
 COLON
 POUND
@@ -119,4 +128,4 @@ mode names:
 DEFAULT_MODE
 
 atn:
-[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 37, 255, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9,  [...]
\ No newline at end of file
+[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 40, 267, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9,  [...]
\ No newline at end of file
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDslLexer.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDslLexer.java
index 461fbae..3c4fbb0 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDslLexer.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDslLexer.java
@@ -20,8 +20,8 @@ public class NCSynonymDslLexer extends Lexer {
 		T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, T__5=6, T__6=7, T__7=8, T__8=9, 
 		SQSTRING=10, DQSTRING=11, PRED_OP=12, AND=13, OR=14, EXCL=15, LPAREN=16, 
 		RPAREN=17, SQUOTE=18, DQUOTE=19, DOLLAR=20, TILDA=21, LBR=22, RBR=23, 
-		COMMA=24, COLON=25, POUND=26, MINUS=27, DOT=28, UNDERSCORE=29, BOOL=30, 
-		INT=31, EXP=32, ID=33, WS=34, ErrorCharacter=35;
+		PLUS=24, STAR=25, DEVIDE=26, COMMA=27, COLON=28, POUND=29, MINUS=30, DOT=31, 
+		UNDERSCORE=32, BOOL=33, INT=34, EXP=35, ID=36, WS=37, ErrorCharacter=38;
 	public static String[] channelNames = {
 		"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
 	};
@@ -34,9 +34,9 @@ public class NCSynonymDslLexer extends Lexer {
 		return new String[] {
 			"T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "T__7", "T__8", 
 			"SQSTRING", "DQSTRING", "PRED_OP", "AND", "OR", "EXCL", "LPAREN", "RPAREN", 
-			"SQUOTE", "DQUOTE", "DOLLAR", "TILDA", "LBR", "RBR", "COMMA", "COLON", 
-			"POUND", "MINUS", "DOT", "UNDERSCORE", "BOOL", "INT", "EXP", "ID", "WS", 
-			"ErrorCharacter"
+			"SQUOTE", "DQUOTE", "DOLLAR", "TILDA", "LBR", "RBR", "PLUS", "STAR", 
+			"DEVIDE", "COMMA", "COLON", "POUND", "MINUS", "DOT", "UNDERSCORE", "BOOL", 
+			"INT", "EXP", "ID", "WS", "ErrorCharacter"
 		};
 	}
 	public static final String[] ruleNames = makeRuleNames();
@@ -45,8 +45,8 @@ public class NCSynonymDslLexer extends Lexer {
 		return new String[] {
 			null, "'null'", "'id'", "'aliases'", "'startidx'", "'endidx'", "'parent'", 
 			"'groups'", "'ancestors'", "'value'", null, null, null, "'&&'", "'||'", 
-			"'!'", "'('", "')'", "'''", "'\"'", "'$'", "'~'", "'['", "']'", "','", 
-			"':'", "'#'", "'-'", "'.'", "'_'"
+			"'!'", "'('", "')'", "'''", "'\"'", "'$'", "'~'", "'['", "']'", "'+'", 
+			"'*'", "'/'", "','", "':'", "'#'", "'-'", "'.'", "'_'"
 		};
 	}
 	private static final String[] _LITERAL_NAMES = makeLiteralNames();
@@ -54,8 +54,9 @@ public class NCSynonymDslLexer extends Lexer {
 		return new String[] {
 			null, null, null, null, null, null, null, null, null, null, "SQSTRING", 
 			"DQSTRING", "PRED_OP", "AND", "OR", "EXCL", "LPAREN", "RPAREN", "SQUOTE", 
-			"DQUOTE", "DOLLAR", "TILDA", "LBR", "RBR", "COMMA", "COLON", "POUND", 
-			"MINUS", "DOT", "UNDERSCORE", "BOOL", "INT", "EXP", "ID", "WS", "ErrorCharacter"
+			"DQUOTE", "DOLLAR", "TILDA", "LBR", "RBR", "PLUS", "STAR", "DEVIDE", 
+			"COMMA", "COLON", "POUND", "MINUS", "DOT", "UNDERSCORE", "BOOL", "INT", 
+			"EXP", "ID", "WS", "ErrorCharacter"
 		};
 	}
 	private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames();
@@ -117,89 +118,93 @@ public class NCSynonymDslLexer extends Lexer {
 	public ATN getATN() { return _ATN; }
 
 	public static final String _serializedATN =
-		"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2%\u00ff\b\1\4\2\t"+
+		"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2(\u010b\b\1\4\2\t"+
 		"\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+
 		"\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+
 		"\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+
 		"\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"+
-		"\t!\4\"\t\"\4#\t#\4$\t$\3\2\3\2\3\2\3\2\3\2\3\3\3\3\3\3\3\4\3\4\3\4\3"+
-		"\4\3\4\3\4\3\4\3\4\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\6\3\6\3\6\3\6"+
-		"\3\6\3\6\3\6\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3"+
-		"\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\n\3\n\3\n\3\n\3\n\3\n\3\13\3"+
-		"\13\7\13\u008a\n\13\f\13\16\13\u008d\13\13\3\13\3\13\3\f\3\f\7\f\u0093"+
-		"\n\f\f\f\16\f\u0096\13\f\3\f\3\f\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3"+
-		"\r\3\r\3\r\3\r\5\r\u00a7\n\r\3\16\3\16\3\16\3\17\3\17\3\17\3\20\3\20\3"+
-		"\21\3\21\3\22\3\22\3\23\3\23\3\24\3\24\3\25\3\25\3\26\3\26\3\27\3\27\3"+
-		"\30\3\30\3\31\3\31\3\32\3\32\3\33\3\33\3\34\3\34\3\35\3\35\3\36\3\36\3"+
-		"\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\5\37\u00d6\n\37\3 \3 \3 \7"+
-		" \u00db\n \f \16 \u00de\13 \5 \u00e0\n \3!\3!\6!\u00e4\n!\r!\16!\u00e5"+
-		"\3\"\3\"\6\"\u00ea\n\"\r\"\16\"\u00eb\3\"\3\"\3\"\3\"\7\"\u00f2\n\"\f"+
-		"\"\16\"\u00f5\13\"\3#\6#\u00f8\n#\r#\16#\u00f9\3#\3#\3$\3$\2\2%\3\3\5"+
-		"\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20\37\21"+
-		"!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67\359\36;\37= ?!"+
-		"A\"C#E$G%\3\2\13\3\2))\3\2$$\4\2>>@@\3\2\63;\4\2\62;aa\3\2\62;\4\2C\\"+
-		"c|\5\2\62;C\\c|\5\2\13\f\16\17\"\"\2\u0111\2\3\3\2\2\2\2\5\3\2\2\2\2\7"+
-		"\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2"+
-		"\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2"+
-		"\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2"+
-		"\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2"+
-		"\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2"+
-		"\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\3I\3\2\2\2\5N\3\2\2\2\7Q"+
-		"\3\2\2\2\tY\3\2\2\2\13b\3\2\2\2\ri\3\2\2\2\17p\3\2\2\2\21w\3\2\2\2\23"+
-		"\u0081\3\2\2\2\25\u0087\3\2\2\2\27\u0090\3\2\2\2\31\u00a6\3\2\2\2\33\u00a8"+
-		"\3\2\2\2\35\u00ab\3\2\2\2\37\u00ae\3\2\2\2!\u00b0\3\2\2\2#\u00b2\3\2\2"+
-		"\2%\u00b4\3\2\2\2\'\u00b6\3\2\2\2)\u00b8\3\2\2\2+\u00ba\3\2\2\2-\u00bc"+
-		"\3\2\2\2/\u00be\3\2\2\2\61\u00c0\3\2\2\2\63\u00c2\3\2\2\2\65\u00c4\3\2"+
-		"\2\2\67\u00c6\3\2\2\29\u00c8\3\2\2\2;\u00ca\3\2\2\2=\u00d5\3\2\2\2?\u00df"+
-		"\3\2\2\2A\u00e1\3\2\2\2C\u00e9\3\2\2\2E\u00f7\3\2\2\2G\u00fd\3\2\2\2I"+
-		"J\7p\2\2JK\7w\2\2KL\7n\2\2LM\7n\2\2M\4\3\2\2\2NO\7k\2\2OP\7f\2\2P\6\3"+
-		"\2\2\2QR\7c\2\2RS\7n\2\2ST\7k\2\2TU\7c\2\2UV\7u\2\2VW\7g\2\2WX\7u\2\2"+
-		"X\b\3\2\2\2YZ\7u\2\2Z[\7v\2\2[\\\7c\2\2\\]\7t\2\2]^\7v\2\2^_\7k\2\2_`"+
-		"\7f\2\2`a\7z\2\2a\n\3\2\2\2bc\7g\2\2cd\7p\2\2de\7f\2\2ef\7k\2\2fg\7f\2"+
-		"\2gh\7z\2\2h\f\3\2\2\2ij\7r\2\2jk\7c\2\2kl\7t\2\2lm\7g\2\2mn\7p\2\2no"+
-		"\7v\2\2o\16\3\2\2\2pq\7i\2\2qr\7t\2\2rs\7q\2\2st\7w\2\2tu\7r\2\2uv\7u"+
-		"\2\2v\20\3\2\2\2wx\7c\2\2xy\7p\2\2yz\7e\2\2z{\7g\2\2{|\7u\2\2|}\7v\2\2"+
-		"}~\7q\2\2~\177\7t\2\2\177\u0080\7u\2\2\u0080\22\3\2\2\2\u0081\u0082\7"+
-		"x\2\2\u0082\u0083\7c\2\2\u0083\u0084\7n\2\2\u0084\u0085\7w\2\2\u0085\u0086"+
-		"\7g\2\2\u0086\24\3\2\2\2\u0087\u008b\5%\23\2\u0088\u008a\n\2\2\2\u0089"+
-		"\u0088\3\2\2\2\u008a\u008d\3\2\2\2\u008b\u0089\3\2\2\2\u008b\u008c\3\2"+
-		"\2\2\u008c\u008e\3\2\2\2\u008d\u008b\3\2\2\2\u008e\u008f\5%\23\2\u008f"+
-		"\26\3\2\2\2\u0090\u0094\5\'\24\2\u0091\u0093\n\3\2\2\u0092\u0091\3\2\2"+
-		"\2\u0093\u0096\3\2\2\2\u0094\u0092\3\2\2\2\u0094\u0095\3\2\2\2\u0095\u0097"+
-		"\3\2\2\2\u0096\u0094\3\2\2\2\u0097\u0098\5\'\24\2\u0098\30\3\2\2\2\u0099"+
-		"\u009a\7?\2\2\u009a\u00a7\7?\2\2\u009b\u009c\7#\2\2\u009c\u00a7\7?\2\2"+
-		"\u009d\u009e\7@\2\2\u009e\u00a7\7?\2\2\u009f\u00a0\7>\2\2\u00a0\u00a7"+
-		"\7?\2\2\u00a1\u00a7\t\4\2\2\u00a2\u00a3\7B\2\2\u00a3\u00a7\7B\2\2\u00a4"+
-		"\u00a5\7#\2\2\u00a5\u00a7\7B\2\2\u00a6\u0099\3\2\2\2\u00a6\u009b\3\2\2"+
-		"\2\u00a6\u009d\3\2\2\2\u00a6\u009f\3\2\2\2\u00a6\u00a1\3\2\2\2\u00a6\u00a2"+
-		"\3\2\2\2\u00a6\u00a4\3\2\2\2\u00a7\32\3\2\2\2\u00a8\u00a9\7(\2\2\u00a9"+
-		"\u00aa\7(\2\2\u00aa\34\3\2\2\2\u00ab\u00ac\7~\2\2\u00ac\u00ad\7~\2\2\u00ad"+
-		"\36\3\2\2\2\u00ae\u00af\7#\2\2\u00af \3\2\2\2\u00b0\u00b1\7*\2\2\u00b1"+
-		"\"\3\2\2\2\u00b2\u00b3\7+\2\2\u00b3$\3\2\2\2\u00b4\u00b5\7)\2\2\u00b5"+
-		"&\3\2\2\2\u00b6\u00b7\7$\2\2\u00b7(\3\2\2\2\u00b8\u00b9\7&\2\2\u00b9*"+
-		"\3\2\2\2\u00ba\u00bb\7\u0080\2\2\u00bb,\3\2\2\2\u00bc\u00bd\7]\2\2\u00bd"+
-		".\3\2\2\2\u00be\u00bf\7_\2\2\u00bf\60\3\2\2\2\u00c0\u00c1\7.\2\2\u00c1"+
-		"\62\3\2\2\2\u00c2\u00c3\7<\2\2\u00c3\64\3\2\2\2\u00c4\u00c5\7%\2\2\u00c5"+
-		"\66\3\2\2\2\u00c6\u00c7\7/\2\2\u00c78\3\2\2\2\u00c8\u00c9\7\60\2\2\u00c9"+
-		":\3\2\2\2\u00ca\u00cb\7a\2\2\u00cb<\3\2\2\2\u00cc\u00cd\7v\2\2\u00cd\u00ce"+
-		"\7t\2\2\u00ce\u00cf\7w\2\2\u00cf\u00d6\7g\2\2\u00d0\u00d1\7h\2\2\u00d1"+
-		"\u00d2\7c\2\2\u00d2\u00d3\7n\2\2\u00d3\u00d4\7u\2\2\u00d4\u00d6\7g\2\2"+
-		"\u00d5\u00cc\3\2\2\2\u00d5\u00d0\3\2\2\2\u00d6>\3\2\2\2\u00d7\u00e0\7"+
-		"\62\2\2\u00d8\u00dc\t\5\2\2\u00d9\u00db\t\6\2\2\u00da\u00d9\3\2\2\2\u00db"+
-		"\u00de\3\2\2\2\u00dc\u00da\3\2\2\2\u00dc\u00dd\3\2\2\2\u00dd\u00e0\3\2"+
-		"\2\2\u00de\u00dc\3\2\2\2\u00df\u00d7\3\2\2\2\u00df\u00d8\3\2\2\2\u00e0"+
-		"@\3\2\2\2\u00e1\u00e3\59\35\2\u00e2\u00e4\t\7\2\2\u00e3\u00e2\3\2\2\2"+
-		"\u00e4\u00e5\3\2\2\2\u00e5\u00e3\3\2\2\2\u00e5\u00e6\3\2\2\2\u00e6B\3"+
-		"\2\2\2\u00e7\u00ea\5;\36\2\u00e8\u00ea\t\b\2\2\u00e9\u00e7\3\2\2\2\u00e9"+
-		"\u00e8\3\2\2\2\u00ea\u00eb\3\2\2\2\u00eb\u00e9\3\2\2\2\u00eb\u00ec\3\2"+
-		"\2\2\u00ec\u00f3\3\2\2\2\u00ed\u00f2\t\t\2\2\u00ee\u00f2\5\63\32\2\u00ef"+
-		"\u00f2\5\67\34\2\u00f0\u00f2\5;\36\2\u00f1\u00ed\3\2\2\2\u00f1\u00ee\3"+
-		"\2\2\2\u00f1\u00ef\3\2\2\2\u00f1\u00f0\3\2\2\2\u00f2\u00f5\3\2\2\2\u00f3"+
-		"\u00f1\3\2\2\2\u00f3\u00f4\3\2\2\2\u00f4D\3\2\2\2\u00f5\u00f3\3\2\2\2"+
-		"\u00f6\u00f8\t\n\2\2\u00f7\u00f6\3\2\2\2\u00f8\u00f9\3\2\2\2\u00f9\u00f7"+
-		"\3\2\2\2\u00f9\u00fa\3\2\2\2\u00fa\u00fb\3\2\2\2\u00fb\u00fc\b#\2\2\u00fc"+
-		"F\3\2\2\2\u00fd\u00fe\13\2\2\2\u00feH\3\2\2\2\17\2\u008b\u0094\u00a6\u00d5"+
-		"\u00dc\u00df\u00e5\u00e9\u00eb\u00f1\u00f3\u00f9\3\b\2\2";
+		"\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\3\2\3\2\3\2\3\2\3\2\3\3\3"+
+		"\3\3\3\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5"+
+		"\3\5\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\b\3\b\3"+
+		"\b\3\b\3\b\3\b\3\b\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\n\3\n\3\n"+
+		"\3\n\3\n\3\n\3\13\3\13\7\13\u0090\n\13\f\13\16\13\u0093\13\13\3\13\3\13"+
+		"\3\f\3\f\7\f\u0099\n\f\f\f\16\f\u009c\13\f\3\f\3\f\3\r\3\r\3\r\3\r\3\r"+
+		"\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\5\r\u00ad\n\r\3\16\3\16\3\16\3\17\3\17"+
+		"\3\17\3\20\3\20\3\21\3\21\3\22\3\22\3\23\3\23\3\24\3\24\3\25\3\25\3\26"+
+		"\3\26\3\27\3\27\3\30\3\30\3\31\3\31\3\32\3\32\3\33\3\33\3\34\3\34\3\35"+
+		"\3\35\3\36\3\36\3\37\3\37\3 \3 \3!\3!\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\""+
+		"\3\"\5\"\u00e2\n\"\3#\3#\3#\7#\u00e7\n#\f#\16#\u00ea\13#\5#\u00ec\n#\3"+
+		"$\3$\6$\u00f0\n$\r$\16$\u00f1\3%\3%\6%\u00f6\n%\r%\16%\u00f7\3%\3%\3%"+
+		"\3%\7%\u00fe\n%\f%\16%\u0101\13%\3&\6&\u0104\n&\r&\16&\u0105\3&\3&\3\'"+
+		"\3\'\2\2(\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33"+
+		"\17\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67"+
+		"\359\36;\37= ?!A\"C#E$G%I&K\'M(\3\2\13\3\2))\3\2$$\4\2>>@@\3\2\63;\4\2"+
+		"\62;aa\3\2\62;\4\2C\\c|\5\2\62;C\\c|\5\2\13\f\16\17\"\"\2\u011d\2\3\3"+
+		"\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2"+
+		"\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3"+
+		"\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2"+
+		"%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61"+
+		"\3\2\2\2\2\63\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2"+
+		"\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I"+
+		"\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\3O\3\2\2\2\5T\3\2\2\2\7W\3\2\2\2\t_\3\2"+
+		"\2\2\13h\3\2\2\2\ro\3\2\2\2\17v\3\2\2\2\21}\3\2\2\2\23\u0087\3\2\2\2\25"+
+		"\u008d\3\2\2\2\27\u0096\3\2\2\2\31\u00ac\3\2\2\2\33\u00ae\3\2\2\2\35\u00b1"+
+		"\3\2\2\2\37\u00b4\3\2\2\2!\u00b6\3\2\2\2#\u00b8\3\2\2\2%\u00ba\3\2\2\2"+
+		"\'\u00bc\3\2\2\2)\u00be\3\2\2\2+\u00c0\3\2\2\2-\u00c2\3\2\2\2/\u00c4\3"+
+		"\2\2\2\61\u00c6\3\2\2\2\63\u00c8\3\2\2\2\65\u00ca\3\2\2\2\67\u00cc\3\2"+
+		"\2\29\u00ce\3\2\2\2;\u00d0\3\2\2\2=\u00d2\3\2\2\2?\u00d4\3\2\2\2A\u00d6"+
+		"\3\2\2\2C\u00e1\3\2\2\2E\u00eb\3\2\2\2G\u00ed\3\2\2\2I\u00f5\3\2\2\2K"+
+		"\u0103\3\2\2\2M\u0109\3\2\2\2OP\7p\2\2PQ\7w\2\2QR\7n\2\2RS\7n\2\2S\4\3"+
+		"\2\2\2TU\7k\2\2UV\7f\2\2V\6\3\2\2\2WX\7c\2\2XY\7n\2\2YZ\7k\2\2Z[\7c\2"+
+		"\2[\\\7u\2\2\\]\7g\2\2]^\7u\2\2^\b\3\2\2\2_`\7u\2\2`a\7v\2\2ab\7c\2\2"+
+		"bc\7t\2\2cd\7v\2\2de\7k\2\2ef\7f\2\2fg\7z\2\2g\n\3\2\2\2hi\7g\2\2ij\7"+
+		"p\2\2jk\7f\2\2kl\7k\2\2lm\7f\2\2mn\7z\2\2n\f\3\2\2\2op\7r\2\2pq\7c\2\2"+
+		"qr\7t\2\2rs\7g\2\2st\7p\2\2tu\7v\2\2u\16\3\2\2\2vw\7i\2\2wx\7t\2\2xy\7"+
+		"q\2\2yz\7w\2\2z{\7r\2\2{|\7u\2\2|\20\3\2\2\2}~\7c\2\2~\177\7p\2\2\177"+
+		"\u0080\7e\2\2\u0080\u0081\7g\2\2\u0081\u0082\7u\2\2\u0082\u0083\7v\2\2"+
+		"\u0083\u0084\7q\2\2\u0084\u0085\7t\2\2\u0085\u0086\7u\2\2\u0086\22\3\2"+
+		"\2\2\u0087\u0088\7x\2\2\u0088\u0089\7c\2\2\u0089\u008a\7n\2\2\u008a\u008b"+
+		"\7w\2\2\u008b\u008c\7g\2\2\u008c\24\3\2\2\2\u008d\u0091\5%\23\2\u008e"+
+		"\u0090\n\2\2\2\u008f\u008e\3\2\2\2\u0090\u0093\3\2\2\2\u0091\u008f\3\2"+
+		"\2\2\u0091\u0092\3\2\2\2\u0092\u0094\3\2\2\2\u0093\u0091\3\2\2\2\u0094"+
+		"\u0095\5%\23\2\u0095\26\3\2\2\2\u0096\u009a\5\'\24\2\u0097\u0099\n\3\2"+
+		"\2\u0098\u0097\3\2\2\2\u0099\u009c\3\2\2\2\u009a\u0098\3\2\2\2\u009a\u009b"+
+		"\3\2\2\2\u009b\u009d\3\2\2\2\u009c\u009a\3\2\2\2\u009d\u009e\5\'\24\2"+
+		"\u009e\30\3\2\2\2\u009f\u00a0\7?\2\2\u00a0\u00ad\7?\2\2\u00a1\u00a2\7"+
+		"#\2\2\u00a2\u00ad\7?\2\2\u00a3\u00a4\7@\2\2\u00a4\u00ad\7?\2\2\u00a5\u00a6"+
+		"\7>\2\2\u00a6\u00ad\7?\2\2\u00a7\u00ad\t\4\2\2\u00a8\u00a9\7B\2\2\u00a9"+
+		"\u00ad\7B\2\2\u00aa\u00ab\7#\2\2\u00ab\u00ad\7B\2\2\u00ac\u009f\3\2\2"+
+		"\2\u00ac\u00a1\3\2\2\2\u00ac\u00a3\3\2\2\2\u00ac\u00a5\3\2\2\2\u00ac\u00a7"+
+		"\3\2\2\2\u00ac\u00a8\3\2\2\2\u00ac\u00aa\3\2\2\2\u00ad\32\3\2\2\2\u00ae"+
+		"\u00af\7(\2\2\u00af\u00b0\7(\2\2\u00b0\34\3\2\2\2\u00b1\u00b2\7~\2\2\u00b2"+
+		"\u00b3\7~\2\2\u00b3\36\3\2\2\2\u00b4\u00b5\7#\2\2\u00b5 \3\2\2\2\u00b6"+
+		"\u00b7\7*\2\2\u00b7\"\3\2\2\2\u00b8\u00b9\7+\2\2\u00b9$\3\2\2\2\u00ba"+
+		"\u00bb\7)\2\2\u00bb&\3\2\2\2\u00bc\u00bd\7$\2\2\u00bd(\3\2\2\2\u00be\u00bf"+
+		"\7&\2\2\u00bf*\3\2\2\2\u00c0\u00c1\7\u0080\2\2\u00c1,\3\2\2\2\u00c2\u00c3"+
+		"\7]\2\2\u00c3.\3\2\2\2\u00c4\u00c5\7_\2\2\u00c5\60\3\2\2\2\u00c6\u00c7"+
+		"\7-\2\2\u00c7\62\3\2\2\2\u00c8\u00c9\7,\2\2\u00c9\64\3\2\2\2\u00ca\u00cb"+
+		"\7\61\2\2\u00cb\66\3\2\2\2\u00cc\u00cd\7.\2\2\u00cd8\3\2\2\2\u00ce\u00cf"+
+		"\7<\2\2\u00cf:\3\2\2\2\u00d0\u00d1\7%\2\2\u00d1<\3\2\2\2\u00d2\u00d3\7"+
+		"/\2\2\u00d3>\3\2\2\2\u00d4\u00d5\7\60\2\2\u00d5@\3\2\2\2\u00d6\u00d7\7"+
+		"a\2\2\u00d7B\3\2\2\2\u00d8\u00d9\7v\2\2\u00d9\u00da\7t\2\2\u00da\u00db"+
+		"\7w\2\2\u00db\u00e2\7g\2\2\u00dc\u00dd\7h\2\2\u00dd\u00de\7c\2\2\u00de"+
+		"\u00df\7n\2\2\u00df\u00e0\7u\2\2\u00e0\u00e2\7g\2\2\u00e1\u00d8\3\2\2"+
+		"\2\u00e1\u00dc\3\2\2\2\u00e2D\3\2\2\2\u00e3\u00ec\7\62\2\2\u00e4\u00e8"+
+		"\t\5\2\2\u00e5\u00e7\t\6\2\2\u00e6\u00e5\3\2\2\2\u00e7\u00ea\3\2\2\2\u00e8"+
+		"\u00e6\3\2\2\2\u00e8\u00e9\3\2\2\2\u00e9\u00ec\3\2\2\2\u00ea\u00e8\3\2"+
+		"\2\2\u00eb\u00e3\3\2\2\2\u00eb\u00e4\3\2\2\2\u00ecF\3\2\2\2\u00ed\u00ef"+
+		"\5? \2\u00ee\u00f0\t\7\2\2\u00ef\u00ee\3\2\2\2\u00f0\u00f1\3\2\2\2\u00f1"+
+		"\u00ef\3\2\2\2\u00f1\u00f2\3\2\2\2\u00f2H\3\2\2\2\u00f3\u00f6\5A!\2\u00f4"+
+		"\u00f6\t\b\2\2\u00f5\u00f3\3\2\2\2\u00f5\u00f4\3\2\2\2\u00f6\u00f7\3\2"+
+		"\2\2\u00f7\u00f5\3\2\2\2\u00f7\u00f8\3\2\2\2\u00f8\u00ff\3\2\2\2\u00f9"+
+		"\u00fe\t\t\2\2\u00fa\u00fe\59\35\2\u00fb\u00fe\5=\37\2\u00fc\u00fe\5A"+
+		"!\2\u00fd\u00f9\3\2\2\2\u00fd\u00fa\3\2\2\2\u00fd\u00fb\3\2\2\2\u00fd"+
+		"\u00fc\3\2\2\2\u00fe\u0101\3\2\2\2\u00ff\u00fd\3\2\2\2\u00ff\u0100\3\2"+
+		"\2\2\u0100J\3\2\2\2\u0101\u00ff\3\2\2\2\u0102\u0104\t\n\2\2\u0103\u0102"+
+		"\3\2\2\2\u0104\u0105\3\2\2\2\u0105\u0103\3\2\2\2\u0105\u0106\3\2\2\2\u0106"+
+		"\u0107\3\2\2\2\u0107\u0108\b&\2\2\u0108L\3\2\2\2\u0109\u010a\13\2\2\2"+
+		"\u010aN\3\2\2\2\17\2\u0091\u009a\u00ac\u00e1\u00e8\u00eb\u00f1\u00f5\u00f7"+
+		"\u00fd\u00ff\u0105\3\b\2\2";
 	public static final ATN _ATN =
 		new ATNDeserializer().deserialize(_serializedATN.toCharArray());
 	static {
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDslLexer.tokens b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDslLexer.tokens
index 7d51b56..041c397 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDslLexer.tokens
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDslLexer.tokens
@@ -21,18 +21,21 @@ DOLLAR=20
 TILDA=21
 LBR=22
 RBR=23
-COMMA=24
-COLON=25
-POUND=26
-MINUS=27
-DOT=28
-UNDERSCORE=29
-BOOL=30
-INT=31
-EXP=32
-ID=33
-WS=34
-ErrorCharacter=35
+PLUS=24
+STAR=25
+DEVIDE=26
+COMMA=27
+COLON=28
+POUND=29
+MINUS=30
+DOT=31
+UNDERSCORE=32
+BOOL=33
+INT=34
+EXP=35
+ID=36
+WS=37
+ErrorCharacter=38
 'null'=1
 'id'=2
 'aliases'=3
@@ -53,9 +56,12 @@ ErrorCharacter=35
 '~'=21
 '['=22
 ']'=23
-','=24
-':'=25
-'#'=26
-'-'=27
-'.'=28
-'_'=29
+'+'=24
+'*'=25
+'/'=26
+','=27
+':'=28
+'#'=29
+'-'=30
+'.'=31
+'_'=32
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDslListener.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDslListener.java
index a22ba9a..146ef51 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDslListener.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDslListener.java
@@ -58,6 +58,16 @@ public interface NCSynonymDslListener extends ParseTreeListener {
 	 */
 	void exitExpr(NCSynonymDslParser.ExprContext ctx);
 	/**
+	 * Enter a parse tree produced by {@link NCSynonymDslParser#mathOp}.
+	 * @param ctx the parse tree
+	 */
+	void enterMathOp(NCSynonymDslParser.MathOpContext ctx);
+	/**
+	 * Exit a parse tree produced by {@link NCSynonymDslParser#mathOp}.
+	 * @param ctx the parse tree
+	 */
+	void exitMathOp(NCSynonymDslParser.MathOpContext ctx);
+	/**
 	 * Enter a parse tree produced by {@link NCSynonymDslParser#val}.
 	 * @param ctx the parse tree
 	 */
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDslParser.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDslParser.java
index ea65684..33047ef 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDslParser.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/antlr4/NCSynonymDslParser.java
@@ -20,16 +20,16 @@ public class NCSynonymDslParser extends Parser {
 		T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, T__5=6, T__6=7, T__7=8, T__8=9, 
 		SQSTRING=10, DQSTRING=11, PRED_OP=12, AND=13, OR=14, EXCL=15, LPAREN=16, 
 		RPAREN=17, SQUOTE=18, DQUOTE=19, DOLLAR=20, TILDA=21, LBR=22, RBR=23, 
-		COMMA=24, COLON=25, POUND=26, MINUS=27, DOT=28, UNDERSCORE=29, BOOL=30, 
-		INT=31, EXP=32, ID=33, WS=34, ErrorCharacter=35;
+		PLUS=24, STAR=25, DEVIDE=26, COMMA=27, COLON=28, POUND=29, MINUS=30, DOT=31, 
+		UNDERSCORE=32, BOOL=33, INT=34, EXP=35, ID=36, WS=37, ErrorCharacter=38;
 	public static final int
 		RULE_synonym = 0, RULE_alias = 1, RULE_item = 2, RULE_pred = 3, RULE_expr = 4, 
-		RULE_val = 5, RULE_singleVal = 6, RULE_tokQual = 7, RULE_tokQualPart = 8, 
-		RULE_tokMeta = 9, RULE_modelMeta = 10, RULE_intentMeta = 11, RULE_qstring = 12;
+		RULE_mathOp = 5, RULE_val = 6, RULE_singleVal = 7, RULE_tokQual = 8, RULE_tokQualPart = 9, 
+		RULE_tokMeta = 10, RULE_modelMeta = 11, RULE_intentMeta = 12, RULE_qstring = 13;
 	private static String[] makeRuleNames() {
 		return new String[] {
-			"synonym", "alias", "item", "pred", "expr", "val", "singleVal", "tokQual", 
-			"tokQualPart", "tokMeta", "modelMeta", "intentMeta", "qstring"
+			"synonym", "alias", "item", "pred", "expr", "mathOp", "val", "singleVal", 
+			"tokQual", "tokQualPart", "tokMeta", "modelMeta", "intentMeta", "qstring"
 		};
 	}
 	public static final String[] ruleNames = makeRuleNames();
@@ -38,8 +38,8 @@ public class NCSynonymDslParser extends Parser {
 		return new String[] {
 			null, "'null'", "'id'", "'aliases'", "'startidx'", "'endidx'", "'parent'", 
 			"'groups'", "'ancestors'", "'value'", null, null, null, "'&&'", "'||'", 
-			"'!'", "'('", "')'", "'''", "'\"'", "'$'", "'~'", "'['", "']'", "','", 
-			"':'", "'#'", "'-'", "'.'", "'_'"
+			"'!'", "'('", "')'", "'''", "'\"'", "'$'", "'~'", "'['", "']'", "'+'", 
+			"'*'", "'/'", "','", "':'", "'#'", "'-'", "'.'", "'_'"
 		};
 	}
 	private static final String[] _LITERAL_NAMES = makeLiteralNames();
@@ -47,8 +47,9 @@ public class NCSynonymDslParser extends Parser {
 		return new String[] {
 			null, null, null, null, null, null, null, null, null, null, "SQSTRING", 
 			"DQSTRING", "PRED_OP", "AND", "OR", "EXCL", "LPAREN", "RPAREN", "SQUOTE", 
-			"DQUOTE", "DOLLAR", "TILDA", "LBR", "RBR", "COMMA", "COLON", "POUND", 
-			"MINUS", "DOT", "UNDERSCORE", "BOOL", "INT", "EXP", "ID", "WS", "ErrorCharacter"
+			"DQUOTE", "DOLLAR", "TILDA", "LBR", "RBR", "PLUS", "STAR", "DEVIDE", 
+			"COMMA", "COLON", "POUND", "MINUS", "DOT", "UNDERSCORE", "BOOL", "INT", 
+			"EXP", "ID", "WS", "ErrorCharacter"
 		};
 	}
 	private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames();
@@ -130,21 +131,21 @@ public class NCSynonymDslParser extends Parser {
 		SynonymContext _localctx = new SynonymContext(_ctx, getState());
 		enterRule(_localctx, 0, RULE_synonym);
 		try {
-			setState(35);
+			setState(37);
 			_errHandler.sync(this);
 			switch (_input.LA(1)) {
 			case LBR:
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(26);
+				setState(28);
 				alias();
-				setState(27);
+				setState(29);
 				match(LPAREN);
-				setState(28);
+				setState(30);
 				item(0);
-				setState(29);
+				setState(31);
 				match(RPAREN);
-				setState(30);
+				setState(32);
 				match(EOF);
 				}
 				break;
@@ -170,9 +171,9 @@ public class NCSynonymDslParser extends Parser {
 			case ID:
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(32);
+				setState(34);
 				item(0);
-				setState(33);
+				setState(35);
 				match(EOF);
 				}
 				break;
@@ -215,11 +216,11 @@ public class NCSynonymDslParser extends Parser {
 		try {
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(37);
+			setState(39);
 			match(LBR);
-			setState(38);
+			setState(40);
 			match(ID);
-			setState(39);
+			setState(41);
 			match(RBR);
 			}
 		}
@@ -279,36 +280,36 @@ public class NCSynonymDslParser extends Parser {
 			int _alt;
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(49);
+			setState(51);
 			_errHandler.sync(this);
 			switch ( getInterpreter().adaptivePredict(_input,1,_ctx) ) {
 			case 1:
 				{
-				setState(42);
+				setState(44);
 				pred();
 				}
 				break;
 			case 2:
 				{
-				setState(43);
+				setState(45);
 				match(LPAREN);
-				setState(44);
+				setState(46);
 				item(0);
-				setState(45);
+				setState(47);
 				match(RPAREN);
 				}
 				break;
 			case 3:
 				{
-				setState(47);
+				setState(49);
 				match(EXCL);
-				setState(48);
+				setState(50);
 				item(1);
 				}
 				break;
 			}
 			_ctx.stop = _input.LT(-1);
-			setState(56);
+			setState(58);
 			_errHandler.sync(this);
 			_alt = getInterpreter().adaptivePredict(_input,2,_ctx);
 			while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
@@ -319,9 +320,9 @@ public class NCSynonymDslParser extends Parser {
 					{
 					_localctx = new ItemContext(_parentctx, _parentState);
 					pushNewRecursionContext(_localctx, _startState, RULE_item);
-					setState(51);
+					setState(53);
 					if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)");
-					setState(52);
+					setState(54);
 					_la = _input.LA(1);
 					if ( !(_la==AND || _la==OR) ) {
 					_errHandler.recoverInline(this);
@@ -331,12 +332,12 @@ public class NCSynonymDslParser extends Parser {
 						_errHandler.reportMatch(this);
 						consume();
 					}
-					setState(53);
+					setState(55);
 					item(3);
 					}
 					} 
 				}
-				setState(58);
+				setState(60);
 				_errHandler.sync(this);
 				_alt = getInterpreter().adaptivePredict(_input,2,_ctx);
 			}
@@ -381,12 +382,12 @@ public class NCSynonymDslParser extends Parser {
 		try {
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(59);
-			expr();
-			setState(60);
-			match(PRED_OP);
 			setState(61);
-			expr();
+			expr(0);
+			setState(62);
+			match(PRED_OP);
+			setState(63);
+			expr(0);
 			}
 		}
 		catch (RecognitionException re) {
@@ -404,12 +405,18 @@ public class NCSynonymDslParser extends Parser {
 		public ValContext val() {
 			return getRuleContext(ValContext.class,0);
 		}
-		public TerminalNode ID() { return getToken(NCSynonymDslParser.ID, 0); }
 		public TerminalNode LPAREN() { return getToken(NCSynonymDslParser.LPAREN, 0); }
-		public ExprContext expr() {
-			return getRuleContext(ExprContext.class,0);
+		public List<ExprContext> expr() {
+			return getRuleContexts(ExprContext.class);
+		}
+		public ExprContext expr(int i) {
+			return getRuleContext(ExprContext.class,i);
 		}
 		public TerminalNode RPAREN() { return getToken(NCSynonymDslParser.RPAREN, 0); }
+		public TerminalNode ID() { return getToken(NCSynonymDslParser.ID, 0); }
+		public MathOpContext mathOp() {
+			return getRuleContext(MathOpContext.class,0);
+		}
 		public ExprContext(ParserRuleContext parent, int invokingState) {
 			super(parent, invokingState);
 		}
@@ -425,33 +432,136 @@ public class NCSynonymDslParser extends Parser {
 	}
 
 	public final ExprContext expr() throws RecognitionException {
-		ExprContext _localctx = new ExprContext(_ctx, getState());
-		enterRule(_localctx, 8, RULE_expr);
+		return expr(0);
+	}
+
+	private ExprContext expr(int _p) throws RecognitionException {
+		ParserRuleContext _parentctx = _ctx;
+		int _parentState = getState();
+		ExprContext _localctx = new ExprContext(_ctx, _parentState);
+		ExprContext _prevctx = _localctx;
+		int _startState = 8;
+		enterRecursionRule(_localctx, 8, RULE_expr, _p);
+		int _la;
 		try {
-			setState(69);
+			int _alt;
+			enterOuterAlt(_localctx, 1);
+			{
+			setState(77);
 			_errHandler.sync(this);
-			switch ( getInterpreter().adaptivePredict(_input,3,_ctx) ) {
+			switch ( getInterpreter().adaptivePredict(_input,4,_ctx) ) {
 			case 1:
-				enterOuterAlt(_localctx, 1);
 				{
-				setState(63);
+				setState(66);
 				val(0);
 				}
 				break;
 			case 2:
-				enterOuterAlt(_localctx, 2);
 				{
-				setState(64);
+				setState(67);
+				match(LPAREN);
+				setState(68);
+				expr(0);
+				setState(69);
+				match(RPAREN);
+				}
+				break;
+			case 3:
+				{
+				setState(71);
 				match(ID);
-				setState(65);
+				setState(72);
 				match(LPAREN);
-				setState(66);
-				expr();
-				setState(67);
+				setState(74);
+				_errHandler.sync(this);
+				_la = _input.LA(1);
+				if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__0) | (1L << T__1) | (1L << T__2) | (1L << T__3) | (1L << T__4) | (1L << T__5) | (1L << T__6) | (1L << T__7) | (1L << T__8) | (1L << SQSTRING) | (1L << DQSTRING) | (1L << LPAREN) | (1L << DOLLAR) | (1L << TILDA) | (1L << POUND) | (1L << MINUS) | (1L << BOOL) | (1L << INT) | (1L << ID))) != 0)) {
+					{
+					setState(73);
+					expr(0);
+					}
+				}
+
+				setState(76);
 				match(RPAREN);
 				}
 				break;
 			}
+			_ctx.stop = _input.LT(-1);
+			setState(85);
+			_errHandler.sync(this);
+			_alt = getInterpreter().adaptivePredict(_input,5,_ctx);
+			while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
+				if ( _alt==1 ) {
+					if ( _parseListeners!=null ) triggerExitRuleEvent();
+					_prevctx = _localctx;
+					{
+					{
+					_localctx = new ExprContext(_parentctx, _parentState);
+					pushNewRecursionContext(_localctx, _startState, RULE_expr);
+					setState(79);
+					if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)");
+					setState(80);
+					mathOp();
+					setState(81);
+					expr(3);
+					}
+					} 
+				}
+				setState(87);
+				_errHandler.sync(this);
+				_alt = getInterpreter().adaptivePredict(_input,5,_ctx);
+			}
+			}
+		}
+		catch (RecognitionException re) {
+			_localctx.exception = re;
+			_errHandler.reportError(this, re);
+			_errHandler.recover(this, re);
+		}
+		finally {
+			unrollRecursionContexts(_parentctx);
+		}
+		return _localctx;
+	}
+
+	public static class MathOpContext extends ParserRuleContext {
+		public TerminalNode MINUS() { return getToken(NCSynonymDslParser.MINUS, 0); }
+		public TerminalNode PLUS() { return getToken(NCSynonymDslParser.PLUS, 0); }
+		public TerminalNode STAR() { return getToken(NCSynonymDslParser.STAR, 0); }
+		public TerminalNode DEVIDE() { return getToken(NCSynonymDslParser.DEVIDE, 0); }
+		public MathOpContext(ParserRuleContext parent, int invokingState) {
+			super(parent, invokingState);
+		}
+		@Override public int getRuleIndex() { return RULE_mathOp; }
+		@Override
+		public void enterRule(ParseTreeListener listener) {
+			if ( listener instanceof NCSynonymDslListener ) ((NCSynonymDslListener)listener).enterMathOp(this);
+		}
+		@Override
+		public void exitRule(ParseTreeListener listener) {
+			if ( listener instanceof NCSynonymDslListener ) ((NCSynonymDslListener)listener).exitMathOp(this);
+		}
+	}
+
+	public final MathOpContext mathOp() throws RecognitionException {
+		MathOpContext _localctx = new MathOpContext(_ctx, getState());
+		enterRule(_localctx, 10, RULE_mathOp);
+		int _la;
+		try {
+			enterOuterAlt(_localctx, 1);
+			{
+			setState(88);
+			_la = _input.LA(1);
+			if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << PLUS) | (1L << STAR) | (1L << DEVIDE) | (1L << MINUS))) != 0)) ) {
+			_errHandler.recoverInline(this);
+			}
+			else {
+				if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
+				_errHandler.reportMatch(this);
+				consume();
+			}
+			}
 		}
 		catch (RecognitionException re) {
 			_localctx.exception = re;
@@ -500,13 +610,13 @@ public class NCSynonymDslParser extends Parser {
 		int _parentState = getState();
 		ValContext _localctx = new ValContext(_ctx, _parentState);
 		ValContext _prevctx = _localctx;
-		int _startState = 10;
-		enterRecursionRule(_localctx, 10, RULE_val, _p);
+		int _startState = 12;
+		enterRecursionRule(_localctx, 12, RULE_val, _p);
 		try {
 			int _alt;
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(77);
+			setState(96);
 			_errHandler.sync(this);
 			switch (_input.LA(1)) {
 			case T__0:
@@ -528,17 +638,17 @@ public class NCSynonymDslParser extends Parser {
 			case INT:
 			case ID:
 				{
-				setState(72);
+				setState(91);
 				singleVal();
 				}
 				break;
 			case LPAREN:
 				{
-				setState(73);
+				setState(92);
 				match(LPAREN);
-				setState(74);
+				setState(93);
 				val(0);
-				setState(75);
+				setState(94);
 				match(RPAREN);
 				}
 				break;
@@ -546,9 +656,9 @@ public class NCSynonymDslParser extends Parser {
 				throw new NoViableAltException(this);
 			}
 			_ctx.stop = _input.LT(-1);
-			setState(84);
+			setState(103);
 			_errHandler.sync(this);
-			_alt = getInterpreter().adaptivePredict(_input,5,_ctx);
+			_alt = getInterpreter().adaptivePredict(_input,7,_ctx);
 			while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
 				if ( _alt==1 ) {
 					if ( _parseListeners!=null ) triggerExitRuleEvent();
@@ -557,18 +667,18 @@ public class NCSynonymDslParser extends Parser {
 					{
 					_localctx = new ValContext(_parentctx, _parentState);
 					pushNewRecursionContext(_localctx, _startState, RULE_val);
-					setState(79);
+					setState(98);
 					if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)");
-					setState(80);
+					setState(99);
 					match(COMMA);
-					setState(81);
+					setState(100);
 					val(2);
 					}
 					} 
 				}
-				setState(86);
+				setState(105);
 				_errHandler.sync(this);
-				_alt = getInterpreter().adaptivePredict(_input,5,_ctx);
+				_alt = getInterpreter().adaptivePredict(_input,7,_ctx);
 			}
 			}
 		}
@@ -619,46 +729,46 @@ public class NCSynonymDslParser extends Parser {
 
 	public final SingleValContext singleVal() throws RecognitionException {
 		SingleValContext _localctx = new SingleValContext(_ctx, getState());
-		enterRule(_localctx, 12, RULE_singleVal);
+		enterRule(_localctx, 14, RULE_singleVal);
 		int _la;
 		try {
-			setState(108);
+			setState(127);
 			_errHandler.sync(this);
-			switch ( getInterpreter().adaptivePredict(_input,10,_ctx) ) {
+			switch ( getInterpreter().adaptivePredict(_input,12,_ctx) ) {
 			case 1:
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(87);
+				setState(106);
 				match(T__0);
 				}
 				break;
 			case 2:
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(89);
+				setState(108);
 				_errHandler.sync(this);
 				_la = _input.LA(1);
 				if (_la==MINUS) {
 					{
-					setState(88);
+					setState(107);
 					match(MINUS);
 					}
 				}
 
-				setState(94);
+				setState(113);
 				_errHandler.sync(this);
-				switch ( getInterpreter().adaptivePredict(_input,7,_ctx) ) {
+				switch ( getInterpreter().adaptivePredict(_input,9,_ctx) ) {
 				case 1:
 					{
-					setState(91);
+					setState(110);
 					match(INT);
 					}
 					break;
 				case 2:
 					{
-					setState(92);
+					setState(111);
 					match(INT);
-					setState(93);
+					setState(112);
 					match(EXP);
 					}
 					break;
@@ -668,31 +778,31 @@ public class NCSynonymDslParser extends Parser {
 			case 3:
 				enterOuterAlt(_localctx, 3);
 				{
-				setState(96);
+				setState(115);
 				match(BOOL);
 				}
 				break;
 			case 4:
 				enterOuterAlt(_localctx, 4);
 				{
-				setState(97);
+				setState(116);
 				qstring();
 				}
 				break;
 			case 5:
 				enterOuterAlt(_localctx, 5);
 				{
-				setState(99);
+				setState(118);
 				_errHandler.sync(this);
 				_la = _input.LA(1);
 				if (_la==ID) {
 					{
-					setState(98);
+					setState(117);
 					tokQual(0);
 					}
 				}
 
-				setState(101);
+				setState(120);
 				_la = _input.LA(1);
 				if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__1) | (1L << T__2) | (1L << T__3) | (1L << T__4) | (1L << T__5) | (1L << T__6) | (1L << T__7) | (1L << T__8))) != 0)) ) {
 				_errHandler.recoverInline(this);
@@ -707,31 +817,31 @@ public class NCSynonymDslParser extends Parser {
 			case 6:
 				enterOuterAlt(_localctx, 6);
 				{
-				setState(103);
+				setState(122);
 				_errHandler.sync(this);
 				_la = _input.LA(1);
 				if (_la==ID) {
 					{
-					setState(102);
+					setState(121);
 					tokQual(0);
 					}
 				}
 
-				setState(105);
+				setState(124);
 				tokMeta();
 				}
 				break;
 			case 7:
 				enterOuterAlt(_localctx, 7);
 				{
-				setState(106);
+				setState(125);
 				modelMeta();
 				}
 				break;
 			case 8:
 				enterOuterAlt(_localctx, 8);
 				{
-				setState(107);
+				setState(126);
 				intentMeta();
 				}
 				break;
@@ -778,20 +888,20 @@ public class NCSynonymDslParser extends Parser {
 		int _parentState = getState();
 		TokQualContext _localctx = new TokQualContext(_ctx, _parentState);
 		TokQualContext _prevctx = _localctx;
-		int _startState = 14;
-		enterRecursionRule(_localctx, 14, RULE_tokQual, _p);
+		int _startState = 16;
+		enterRecursionRule(_localctx, 16, RULE_tokQual, _p);
 		try {
 			int _alt;
 			enterOuterAlt(_localctx, 1);
 			{
 			{
-			setState(111);
+			setState(130);
 			tokQualPart();
 			}
 			_ctx.stop = _input.LT(-1);
-			setState(117);
+			setState(136);
 			_errHandler.sync(this);
-			_alt = getInterpreter().adaptivePredict(_input,11,_ctx);
+			_alt = getInterpreter().adaptivePredict(_input,13,_ctx);
 			while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
 				if ( _alt==1 ) {
 					if ( _parseListeners!=null ) triggerExitRuleEvent();
@@ -800,16 +910,16 @@ public class NCSynonymDslParser extends Parser {
 					{
 					_localctx = new TokQualContext(_parentctx, _parentState);
 					pushNewRecursionContext(_localctx, _startState, RULE_tokQual);
-					setState(113);
+					setState(132);
 					if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)");
-					setState(114);
+					setState(133);
 					tokQualPart();
 					}
 					} 
 				}
-				setState(119);
+				setState(138);
 				_errHandler.sync(this);
-				_alt = getInterpreter().adaptivePredict(_input,11,_ctx);
+				_alt = getInterpreter().adaptivePredict(_input,13,_ctx);
 			}
 			}
 		}
@@ -843,13 +953,13 @@ public class NCSynonymDslParser extends Parser {
 
 	public final TokQualPartContext tokQualPart() throws RecognitionException {
 		TokQualPartContext _localctx = new TokQualPartContext(_ctx, getState());
-		enterRule(_localctx, 16, RULE_tokQualPart);
+		enterRule(_localctx, 18, RULE_tokQualPart);
 		try {
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(120);
+			setState(139);
 			match(ID);
-			setState(121);
+			setState(140);
 			match(DOT);
 			}
 		}
@@ -889,47 +999,47 @@ public class NCSynonymDslParser extends Parser {
 
 	public final TokMetaContext tokMeta() throws RecognitionException {
 		TokMetaContext _localctx = new TokMetaContext(_ctx, getState());
-		enterRule(_localctx, 18, RULE_tokMeta);
+		enterRule(_localctx, 20, RULE_tokMeta);
 		try {
-			setState(136);
+			setState(155);
 			_errHandler.sync(this);
-			switch ( getInterpreter().adaptivePredict(_input,12,_ctx) ) {
+			switch ( getInterpreter().adaptivePredict(_input,14,_ctx) ) {
 			case 1:
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(123);
+				setState(142);
 				match(TILDA);
-				setState(124);
+				setState(143);
 				match(ID);
 				}
 				break;
 			case 2:
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(125);
+				setState(144);
 				match(TILDA);
-				setState(126);
+				setState(145);
 				match(ID);
-				setState(127);
+				setState(146);
 				match(LBR);
-				setState(128);
+				setState(147);
 				match(INT);
-				setState(129);
+				setState(148);
 				match(RBR);
 				}
 				break;
 			case 3:
 				enterOuterAlt(_localctx, 3);
 				{
-				setState(130);
+				setState(149);
 				match(TILDA);
-				setState(131);
+				setState(150);
 				match(ID);
-				setState(132);
+				setState(151);
 				match(LBR);
-				setState(133);
+				setState(152);
 				qstring();
-				setState(134);
+				setState(153);
 				match(RBR);
 				}
 				break;
@@ -971,47 +1081,47 @@ public class NCSynonymDslParser extends Parser {
 
 	public final ModelMetaContext modelMeta() throws RecognitionException {
 		ModelMetaContext _localctx = new ModelMetaContext(_ctx, getState());
-		enterRule(_localctx, 20, RULE_modelMeta);
+		enterRule(_localctx, 22, RULE_modelMeta);
 		try {
-			setState(151);
+			setState(170);
 			_errHandler.sync(this);
-			switch ( getInterpreter().adaptivePredict(_input,13,_ctx) ) {
+			switch ( getInterpreter().adaptivePredict(_input,15,_ctx) ) {
 			case 1:
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(138);
+				setState(157);
 				match(POUND);
-				setState(139);
+				setState(158);
 				match(ID);
 				}
 				break;
 			case 2:
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(140);
+				setState(159);
 				match(POUND);
-				setState(141);
+				setState(160);
 				match(ID);
-				setState(142);
+				setState(161);
 				match(LBR);
-				setState(143);
+				setState(162);
 				match(INT);
-				setState(144);
+				setState(163);
 				match(RBR);
 				}
 				break;
 			case 3:
 				enterOuterAlt(_localctx, 3);
 				{
-				setState(145);
+				setState(164);
 				match(POUND);
-				setState(146);
+				setState(165);
 				match(ID);
-				setState(147);
+				setState(166);
 				match(LBR);
-				setState(148);
+				setState(167);
 				qstring();
-				setState(149);
+				setState(168);
 				match(RBR);
 				}
 				break;
@@ -1053,47 +1163,47 @@ public class NCSynonymDslParser extends Parser {
 
 	public final IntentMetaContext intentMeta() throws RecognitionException {
 		IntentMetaContext _localctx = new IntentMetaContext(_ctx, getState());
-		enterRule(_localctx, 22, RULE_intentMeta);
+		enterRule(_localctx, 24, RULE_intentMeta);
 		try {
-			setState(166);
+			setState(185);
 			_errHandler.sync(this);
-			switch ( getInterpreter().adaptivePredict(_input,14,_ctx) ) {
+			switch ( getInterpreter().adaptivePredict(_input,16,_ctx) ) {
 			case 1:
 				enterOuterAlt(_localctx, 1);
 				{
-				setState(153);
+				setState(172);
 				match(DOLLAR);
-				setState(154);
+				setState(173);
 				match(ID);
 				}
 				break;
 			case 2:
 				enterOuterAlt(_localctx, 2);
 				{
-				setState(155);
+				setState(174);
 				match(DOLLAR);
-				setState(156);
+				setState(175);
 				match(ID);
-				setState(157);
+				setState(176);
 				match(LBR);
-				setState(158);
+				setState(177);
 				match(INT);
-				setState(159);
+				setState(178);
 				match(RBR);
 				}
 				break;
 			case 3:
 				enterOuterAlt(_localctx, 3);
 				{
-				setState(160);
+				setState(179);
 				match(DOLLAR);
-				setState(161);
+				setState(180);
 				match(ID);
-				setState(162);
+				setState(181);
 				match(LBR);
-				setState(163);
+				setState(182);
 				qstring();
-				setState(164);
+				setState(183);
 				match(RBR);
 				}
 				break;
@@ -1129,12 +1239,12 @@ public class NCSynonymDslParser extends Parser {
 
 	public final QstringContext qstring() throws RecognitionException {
 		QstringContext _localctx = new QstringContext(_ctx, getState());
-		enterRule(_localctx, 24, RULE_qstring);
+		enterRule(_localctx, 26, RULE_qstring);
 		int _la;
 		try {
 			enterOuterAlt(_localctx, 1);
 			{
-			setState(168);
+			setState(187);
 			_la = _input.LA(1);
 			if ( !(_la==SQSTRING || _la==DQSTRING) ) {
 			_errHandler.recoverInline(this);
@@ -1161,9 +1271,11 @@ public class NCSynonymDslParser extends Parser {
 		switch (ruleIndex) {
 		case 2:
 			return item_sempred((ItemContext)_localctx, predIndex);
-		case 5:
+		case 4:
+			return expr_sempred((ExprContext)_localctx, predIndex);
+		case 6:
 			return val_sempred((ValContext)_localctx, predIndex);
-		case 7:
+		case 8:
 			return tokQual_sempred((TokQualContext)_localctx, predIndex);
 		}
 		return true;
@@ -1175,71 +1287,87 @@ public class NCSynonymDslParser extends Parser {
 		}
 		return true;
 	}
-	private boolean val_sempred(ValContext _localctx, int predIndex) {
+	private boolean expr_sempred(ExprContext _localctx, int predIndex) {
 		switch (predIndex) {
 		case 1:
+			return precpred(_ctx, 2);
+		}
+		return true;
+	}
+	private boolean val_sempred(ValContext _localctx, int predIndex) {
+		switch (predIndex) {
+		case 2:
 			return precpred(_ctx, 1);
 		}
 		return true;
 	}
 	private boolean tokQual_sempred(TokQualContext _localctx, int predIndex) {
 		switch (predIndex) {
-		case 2:
+		case 3:
 			return precpred(_ctx, 1);
 		}
 		return true;
 	}
 
 	public static final String _serializedATN =
-		"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3%\u00ad\4\2\t\2\4"+
+		"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3(\u00c0\4\2\t\2\4"+
 		"\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t"+
-		"\13\4\f\t\f\4\r\t\r\4\16\t\16\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\5\2"+
-		"&\n\2\3\3\3\3\3\3\3\3\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\5\4\64\n\4\3\4\3"+
-		"\4\3\4\7\49\n\4\f\4\16\4<\13\4\3\5\3\5\3\5\3\5\3\6\3\6\3\6\3\6\3\6\3\6"+
-		"\5\6H\n\6\3\7\3\7\3\7\3\7\3\7\3\7\5\7P\n\7\3\7\3\7\3\7\7\7U\n\7\f\7\16"+
-		"\7X\13\7\3\b\3\b\5\b\\\n\b\3\b\3\b\3\b\5\ba\n\b\3\b\3\b\3\b\5\bf\n\b\3"+
-		"\b\3\b\5\bj\n\b\3\b\3\b\3\b\5\bo\n\b\3\t\3\t\3\t\3\t\3\t\7\tv\n\t\f\t"+
-		"\16\ty\13\t\3\n\3\n\3\n\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3"+
-		"\13\3\13\3\13\3\13\5\13\u008b\n\13\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f"+
-		"\3\f\3\f\3\f\3\f\5\f\u009a\n\f\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r"+
-		"\3\r\3\r\3\r\5\r\u00a9\n\r\3\16\3\16\3\16\2\5\6\f\20\17\2\4\6\b\n\f\16"+
-		"\20\22\24\26\30\32\2\5\3\2\17\20\3\2\4\13\3\2\f\r\2\u00b8\2%\3\2\2\2\4"+
-		"\'\3\2\2\2\6\63\3\2\2\2\b=\3\2\2\2\nG\3\2\2\2\fO\3\2\2\2\16n\3\2\2\2\20"+
-		"p\3\2\2\2\22z\3\2\2\2\24\u008a\3\2\2\2\26\u0099\3\2\2\2\30\u00a8\3\2\2"+
-		"\2\32\u00aa\3\2\2\2\34\35\5\4\3\2\35\36\7\22\2\2\36\37\5\6\4\2\37 \7\23"+
-		"\2\2 !\7\2\2\3!&\3\2\2\2\"#\5\6\4\2#$\7\2\2\3$&\3\2\2\2%\34\3\2\2\2%\""+
-		"\3\2\2\2&\3\3\2\2\2\'(\7\30\2\2()\7#\2\2)*\7\31\2\2*\5\3\2\2\2+,\b\4\1"+
-		"\2,\64\5\b\5\2-.\7\22\2\2./\5\6\4\2/\60\7\23\2\2\60\64\3\2\2\2\61\62\7"+
-		"\21\2\2\62\64\5\6\4\3\63+\3\2\2\2\63-\3\2\2\2\63\61\3\2\2\2\64:\3\2\2"+
-		"\2\65\66\f\4\2\2\66\67\t\2\2\2\679\5\6\4\58\65\3\2\2\29<\3\2\2\2:8\3\2"+
-		"\2\2:;\3\2\2\2;\7\3\2\2\2<:\3\2\2\2=>\5\n\6\2>?\7\16\2\2?@\5\n\6\2@\t"+
-		"\3\2\2\2AH\5\f\7\2BC\7#\2\2CD\7\22\2\2DE\5\n\6\2EF\7\23\2\2FH\3\2\2\2"+
-		"GA\3\2\2\2GB\3\2\2\2H\13\3\2\2\2IJ\b\7\1\2JP\5\16\b\2KL\7\22\2\2LM\5\f"+
-		"\7\2MN\7\23\2\2NP\3\2\2\2OI\3\2\2\2OK\3\2\2\2PV\3\2\2\2QR\f\3\2\2RS\7"+
-		"\32\2\2SU\5\f\7\4TQ\3\2\2\2UX\3\2\2\2VT\3\2\2\2VW\3\2\2\2W\r\3\2\2\2X"+
-		"V\3\2\2\2Yo\7\3\2\2Z\\\7\35\2\2[Z\3\2\2\2[\\\3\2\2\2\\`\3\2\2\2]a\7!\2"+
-		"\2^_\7!\2\2_a\7\"\2\2`]\3\2\2\2`^\3\2\2\2ao\3\2\2\2bo\7 \2\2co\5\32\16"+
-		"\2df\5\20\t\2ed\3\2\2\2ef\3\2\2\2fg\3\2\2\2go\t\3\2\2hj\5\20\t\2ih\3\2"+
-		"\2\2ij\3\2\2\2jk\3\2\2\2ko\5\24\13\2lo\5\26\f\2mo\5\30\r\2nY\3\2\2\2n"+
-		"[\3\2\2\2nb\3\2\2\2nc\3\2\2\2ne\3\2\2\2ni\3\2\2\2nl\3\2\2\2nm\3\2\2\2"+
-		"o\17\3\2\2\2pq\b\t\1\2qr\5\22\n\2rw\3\2\2\2st\f\3\2\2tv\5\22\n\2us\3\2"+
-		"\2\2vy\3\2\2\2wu\3\2\2\2wx\3\2\2\2x\21\3\2\2\2yw\3\2\2\2z{\7#\2\2{|\7"+
-		"\36\2\2|\23\3\2\2\2}~\7\27\2\2~\u008b\7#\2\2\177\u0080\7\27\2\2\u0080"+
-		"\u0081\7#\2\2\u0081\u0082\7\30\2\2\u0082\u0083\7!\2\2\u0083\u008b\7\31"+
-		"\2\2\u0084\u0085\7\27\2\2\u0085\u0086\7#\2\2\u0086\u0087\7\30\2\2\u0087"+
-		"\u0088\5\32\16\2\u0088\u0089\7\31\2\2\u0089\u008b\3\2\2\2\u008a}\3\2\2"+
-		"\2\u008a\177\3\2\2\2\u008a\u0084\3\2\2\2\u008b\25\3\2\2\2\u008c\u008d"+
-		"\7\34\2\2\u008d\u009a\7#\2\2\u008e\u008f\7\34\2\2\u008f\u0090\7#\2\2\u0090"+
-		"\u0091\7\30\2\2\u0091\u0092\7!\2\2\u0092\u009a\7\31\2\2\u0093\u0094\7"+
-		"\34\2\2\u0094\u0095\7#\2\2\u0095\u0096\7\30\2\2\u0096\u0097\5\32\16\2"+
-		"\u0097\u0098\7\31\2\2\u0098\u009a\3\2\2\2\u0099\u008c\3\2\2\2\u0099\u008e"+
-		"\3\2\2\2\u0099\u0093\3\2\2\2\u009a\27\3\2\2\2\u009b\u009c\7\26\2\2\u009c"+
-		"\u00a9\7#\2\2\u009d\u009e\7\26\2\2\u009e\u009f\7#\2\2\u009f\u00a0\7\30"+
-		"\2\2\u00a0\u00a1\7!\2\2\u00a1\u00a9\7\31\2\2\u00a2\u00a3\7\26\2\2\u00a3"+
-		"\u00a4\7#\2\2\u00a4\u00a5\7\30\2\2\u00a5\u00a6\5\32\16\2\u00a6\u00a7\7"+
-		"\31\2\2\u00a7\u00a9\3\2\2\2\u00a8\u009b\3\2\2\2\u00a8\u009d\3\2\2\2\u00a8"+
-		"\u00a2\3\2\2\2\u00a9\31\3\2\2\2\u00aa\u00ab\t\4\2\2\u00ab\33\3\2\2\2\21"+
-		"%\63:GOV[`einw\u008a\u0099\u00a8";
+		"\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3"+
+		"\2\3\2\5\2(\n\2\3\3\3\3\3\3\3\3\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\5\4\66"+
+		"\n\4\3\4\3\4\3\4\7\4;\n\4\f\4\16\4>\13\4\3\5\3\5\3\5\3\5\3\6\3\6\3\6\3"+
+		"\6\3\6\3\6\3\6\3\6\3\6\5\6M\n\6\3\6\5\6P\n\6\3\6\3\6\3\6\3\6\7\6V\n\6"+
+		"\f\6\16\6Y\13\6\3\7\3\7\3\b\3\b\3\b\3\b\3\b\3\b\5\bc\n\b\3\b\3\b\3\b\7"+
+		"\bh\n\b\f\b\16\bk\13\b\3\t\3\t\5\to\n\t\3\t\3\t\3\t\5\tt\n\t\3\t\3\t\3"+
+		"\t\5\ty\n\t\3\t\3\t\5\t}\n\t\3\t\3\t\3\t\5\t\u0082\n\t\3\n\3\n\3\n\3\n"+
+		"\3\n\7\n\u0089\n\n\f\n\16\n\u008c\13\n\3\13\3\13\3\13\3\f\3\f\3\f\3\f"+
+		"\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\5\f\u009e\n\f\3\r\3\r\3\r\3\r\3\r"+
+		"\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\5\r\u00ad\n\r\3\16\3\16\3\16\3\16\3\16"+
+		"\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\16\5\16\u00bc\n\16\3\17\3\17\3\17"+
+		"\2\6\6\n\16\22\20\2\4\6\b\n\f\16\20\22\24\26\30\32\34\2\6\3\2\17\20\4"+
+		"\2\32\34  \3\2\4\13\3\2\f\r\2\u00cd\2\'\3\2\2\2\4)\3\2\2\2\6\65\3\2\2"+
+		"\2\b?\3\2\2\2\nO\3\2\2\2\fZ\3\2\2\2\16b\3\2\2\2\20\u0081\3\2\2\2\22\u0083"+
+		"\3\2\2\2\24\u008d\3\2\2\2\26\u009d\3\2\2\2\30\u00ac\3\2\2\2\32\u00bb\3"+
+		"\2\2\2\34\u00bd\3\2\2\2\36\37\5\4\3\2\37 \7\22\2\2 !\5\6\4\2!\"\7\23\2"+
+		"\2\"#\7\2\2\3#(\3\2\2\2$%\5\6\4\2%&\7\2\2\3&(\3\2\2\2\'\36\3\2\2\2\'$"+
+		"\3\2\2\2(\3\3\2\2\2)*\7\30\2\2*+\7&\2\2+,\7\31\2\2,\5\3\2\2\2-.\b\4\1"+
+		"\2.\66\5\b\5\2/\60\7\22\2\2\60\61\5\6\4\2\61\62\7\23\2\2\62\66\3\2\2\2"+
+		"\63\64\7\21\2\2\64\66\5\6\4\3\65-\3\2\2\2\65/\3\2\2\2\65\63\3\2\2\2\66"+
+		"<\3\2\2\2\678\f\4\2\289\t\2\2\29;\5\6\4\5:\67\3\2\2\2;>\3\2\2\2<:\3\2"+
+		"\2\2<=\3\2\2\2=\7\3\2\2\2><\3\2\2\2?@\5\n\6\2@A\7\16\2\2AB\5\n\6\2B\t"+
+		"\3\2\2\2CD\b\6\1\2DP\5\16\b\2EF\7\22\2\2FG\5\n\6\2GH\7\23\2\2HP\3\2\2"+
+		"\2IJ\7&\2\2JL\7\22\2\2KM\5\n\6\2LK\3\2\2\2LM\3\2\2\2MN\3\2\2\2NP\7\23"+
+		"\2\2OC\3\2\2\2OE\3\2\2\2OI\3\2\2\2PW\3\2\2\2QR\f\4\2\2RS\5\f\7\2ST\5\n"+
+		"\6\5TV\3\2\2\2UQ\3\2\2\2VY\3\2\2\2WU\3\2\2\2WX\3\2\2\2X\13\3\2\2\2YW\3"+
+		"\2\2\2Z[\t\3\2\2[\r\3\2\2\2\\]\b\b\1\2]c\5\20\t\2^_\7\22\2\2_`\5\16\b"+
+		"\2`a\7\23\2\2ac\3\2\2\2b\\\3\2\2\2b^\3\2\2\2ci\3\2\2\2de\f\3\2\2ef\7\35"+
+		"\2\2fh\5\16\b\4gd\3\2\2\2hk\3\2\2\2ig\3\2\2\2ij\3\2\2\2j\17\3\2\2\2ki"+
+		"\3\2\2\2l\u0082\7\3\2\2mo\7 \2\2nm\3\2\2\2no\3\2\2\2os\3\2\2\2pt\7$\2"+
+		"\2qr\7$\2\2rt\7%\2\2sp\3\2\2\2sq\3\2\2\2t\u0082\3\2\2\2u\u0082\7#\2\2"+
+		"v\u0082\5\34\17\2wy\5\22\n\2xw\3\2\2\2xy\3\2\2\2yz\3\2\2\2z\u0082\t\4"+
+		"\2\2{}\5\22\n\2|{\3\2\2\2|}\3\2\2\2}~\3\2\2\2~\u0082\5\26\f\2\177\u0082"+
+		"\5\30\r\2\u0080\u0082\5\32\16\2\u0081l\3\2\2\2\u0081n\3\2\2\2\u0081u\3"+
+		"\2\2\2\u0081v\3\2\2\2\u0081x\3\2\2\2\u0081|\3\2\2\2\u0081\177\3\2\2\2"+
+		"\u0081\u0080\3\2\2\2\u0082\21\3\2\2\2\u0083\u0084\b\n\1\2\u0084\u0085"+
+		"\5\24\13\2\u0085\u008a\3\2\2\2\u0086\u0087\f\3\2\2\u0087\u0089\5\24\13"+
+		"\2\u0088\u0086\3\2\2\2\u0089\u008c\3\2\2\2\u008a\u0088\3\2\2\2\u008a\u008b"+
+		"\3\2\2\2\u008b\23\3\2\2\2\u008c\u008a\3\2\2\2\u008d\u008e\7&\2\2\u008e"+
+		"\u008f\7!\2\2\u008f\25\3\2\2\2\u0090\u0091\7\27\2\2\u0091\u009e\7&\2\2"+
+		"\u0092\u0093\7\27\2\2\u0093\u0094\7&\2\2\u0094\u0095\7\30\2\2\u0095\u0096"+
+		"\7$\2\2\u0096\u009e\7\31\2\2\u0097\u0098\7\27\2\2\u0098\u0099\7&\2\2\u0099"+
+		"\u009a\7\30\2\2\u009a\u009b\5\34\17\2\u009b\u009c\7\31\2\2\u009c\u009e"+
+		"\3\2\2\2\u009d\u0090\3\2\2\2\u009d\u0092\3\2\2\2\u009d\u0097\3\2\2\2\u009e"+
+		"\27\3\2\2\2\u009f\u00a0\7\37\2\2\u00a0\u00ad\7&\2\2\u00a1\u00a2\7\37\2"+
+		"\2\u00a2\u00a3\7&\2\2\u00a3\u00a4\7\30\2\2\u00a4\u00a5\7$\2\2\u00a5\u00ad"+
+		"\7\31\2\2\u00a6\u00a7\7\37\2\2\u00a7\u00a8\7&\2\2\u00a8\u00a9\7\30\2\2"+
+		"\u00a9\u00aa\5\34\17\2\u00aa\u00ab\7\31\2\2\u00ab\u00ad\3\2\2\2\u00ac"+
+		"\u009f\3\2\2\2\u00ac\u00a1\3\2\2\2\u00ac\u00a6\3\2\2\2\u00ad\31\3\2\2"+
+		"\2\u00ae\u00af\7\26\2\2\u00af\u00bc\7&\2\2\u00b0\u00b1\7\26\2\2\u00b1"+
+		"\u00b2\7&\2\2\u00b2\u00b3\7\30\2\2\u00b3\u00b4\7$\2\2\u00b4\u00bc\7\31"+
+		"\2\2\u00b5\u00b6\7\26\2\2\u00b6\u00b7\7&\2\2\u00b7\u00b8\7\30\2\2\u00b8"+
+		"\u00b9\5\34\17\2\u00b9\u00ba\7\31\2\2\u00ba\u00bc\3\2\2\2\u00bb\u00ae"+
+		"\3\2\2\2\u00bb\u00b0\3\2\2\2\u00bb\u00b5\3\2\2\2\u00bc\33\3\2\2\2\u00bd"+
+		"\u00be\t\5\2\2\u00be\35\3\2\2\2\23\'\65<LOWbinsx|\u0081\u008a\u009d\u00ac"+
+		"\u00bb";
 	public static final ATN _ATN =
 		new ATNDeserializer().deserialize(_serializedATN.toCharArray());
 	static {