synapse 2.135.0__py38-none-any.whl → 2.136.0__py38-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of synapse might be problematic. Click here for more details.

synapse/cortex.py CHANGED
@@ -82,6 +82,7 @@ import synapse.lib.stormlib.project as s_stormlib_project # NOQA
82
82
  import synapse.lib.stormlib.version as s_stormlib_version # NOQA
83
83
  import synapse.lib.stormlib.ethereum as s_stormlib_ethereum # NOQA
84
84
  import synapse.lib.stormlib.modelext as s_stormlib_modelext # NOQA
85
+ import synapse.lib.stormlib.compression as s_stormlib_compression # NOQA
85
86
  import synapse.lib.stormlib.notifications as s_stormlib_notifications # NOQA
86
87
 
87
88
  logger = logging.getLogger(__name__)
synapse/lib/ast.py CHANGED
@@ -1322,7 +1322,7 @@ class LiftTag(LiftOper):
1322
1322
 
1323
1323
  async def lift(self, runt, path):
1324
1324
 
1325
- tag = await tostr(await self.kids[0].compute(runt, path))
1325
+ tag = await self.kids[0].compute(runt, path)
1326
1326
 
1327
1327
  if len(self.kids) == 3:
1328
1328
 
@@ -1403,7 +1403,7 @@ class LiftTagTag(LiftOper):
1403
1403
 
1404
1404
  async def lift(self, runt, path):
1405
1405
 
1406
- tagname = await tostr(await self.kids[0].compute(runt, path))
1406
+ tagname = await self.kids[0].compute(runt, path)
1407
1407
 
1408
1408
  node = await runt.snap.getNodeByNdef(('syn:tag', tagname))
1409
1409
  if node is None:
@@ -1448,7 +1448,7 @@ class LiftFormTag(LiftOper):
1448
1448
  if not runt.model.form(form):
1449
1449
  raise self.kids[0].addExcInfo(s_exc.NoSuchForm.init(form))
1450
1450
 
1451
- tag = await tostr(await self.kids[1].compute(runt, path))
1451
+ tag = await self.kids[1].compute(runt, path)
1452
1452
 
1453
1453
  if len(self.kids) == 4:
1454
1454
 
@@ -2507,7 +2507,18 @@ class HasTagPropCond(Cond):
2507
2507
  async def getCondEval(self, runt):
2508
2508
 
2509
2509
  async def cond(node, path):
2510
- tag, name = await self.kids[0].compute(runt, path)
2510
+ tag = await self.kids[0].compute(runt, path)
2511
+ name = await self.kids[1].compute(runt, path)
2512
+
2513
+ if tag == '*':
2514
+ return any(name in props for props in node.tagprops.values())
2515
+
2516
+ if '*' in tag:
2517
+ reobj = s_cache.getTagGlobRegx(tag)
2518
+ for tagname, props in node.tagprops.items():
2519
+ if reobj.fullmatch(tagname) and name in props:
2520
+ return True
2521
+
2511
2522
  return node.hasTagProp(tag, name)
2512
2523
 
2513
2524
  return cond
@@ -2707,11 +2718,12 @@ class TagPropCond(Cond):
2707
2718
 
2708
2719
  async def getCondEval(self, runt):
2709
2720
 
2710
- cmpr = await self.kids[1].compute(runt, None)
2721
+ cmpr = await self.kids[2].compute(runt, None)
2711
2722
 
2712
2723
  async def cond(node, path):
2713
2724
 
2714
- tag, name = await self.kids[0].compute(runt, path)
2725
+ tag = await self.kids[0].compute(runt, path)
2726
+ name = await self.kids[1].compute(runt, path)
2715
2727
 
2716
2728
  prop = runt.model.getTagProp(name)
2717
2729
  if prop is None:
@@ -2719,7 +2731,7 @@ class TagPropCond(Cond):
2719
2731
  raise self.kids[0].addExcInfo(s_exc.NoSuchTagProp(name=name, mesg=mesg))
2720
2732
 
2721
2733
  # TODO cache on (cmpr, valu) for perf?
2722
- valu = await self.kids[2].compute(runt, path)
2734
+ valu = await self.kids[3].compute(runt, path)
2723
2735
 
2724
2736
  ctor = prop.type.getCmprCtor(cmpr)
2725
2737
  if ctor is None:
@@ -3086,16 +3098,71 @@ class TagName(Value):
3086
3098
  if self.isconst:
3087
3099
  return self.constval
3088
3100
 
3101
+ if not isinstance(self.kids[0], Const):
3102
+ valu = await self.kids[0].compute(runt, path)
3103
+ valu = await s_stormtypes.toprim(valu)
3104
+
3105
+ if not isinstance(valu, str):
3106
+ mesg = 'Invalid value type for tag name, tag names must be strings.'
3107
+ raise s_exc.BadTypeValu(mesg=mesg)
3108
+
3109
+ normtupl = await runt.snap.getTagNorm(valu)
3110
+ return normtupl[0]
3111
+
3089
3112
  vals = []
3090
3113
  for kid in self.kids:
3091
3114
  part = await kid.compute(runt, path)
3092
3115
  if part is None:
3093
3116
  mesg = f'Null value from var ${kid.name} is not allowed in tag names.'
3094
3117
  raise kid.addExcInfo(s_exc.BadTypeValu(mesg=mesg))
3095
- vals.append(await tostr(part))
3118
+
3119
+ part = await tostr(part)
3120
+ partnorm = await runt.snap.getTagNorm(part)
3121
+ vals.append(partnorm[0])
3096
3122
 
3097
3123
  return '.'.join(vals)
3098
3124
 
3125
+ async def computeTagArray(self, runt, path, excignore=()):
3126
+
3127
+ if self.isconst:
3128
+ return (self.constval,)
3129
+
3130
+ if not isinstance(self.kids[0], Const):
3131
+ tags = []
3132
+ vals = await self.kids[0].compute(runt, path)
3133
+ vals = await s_stormtypes.toprim(vals)
3134
+
3135
+ if not isinstance(vals, (tuple, list, set)):
3136
+ vals = (vals,)
3137
+
3138
+ for valu in vals:
3139
+ try:
3140
+ if not isinstance(valu, str):
3141
+ mesg = 'Invalid value type for tag name, tag names must be strings.'
3142
+ raise s_exc.BadTypeValu(mesg=mesg)
3143
+
3144
+ normtupl = await runt.snap.getTagNorm(valu)
3145
+ if normtupl is None:
3146
+ continue
3147
+
3148
+ tags.append(normtupl[0])
3149
+ except excignore:
3150
+ pass
3151
+ return tags
3152
+
3153
+ vals = []
3154
+ for kid in self.kids:
3155
+ part = await kid.compute(runt, path)
3156
+ if part is None:
3157
+ mesg = f'Null value from var ${kid.name} is not allowed in tag names.'
3158
+ raise kid.addExcInfo(s_exc.BadTypeValu(mesg=mesg))
3159
+
3160
+ part = await tostr(part)
3161
+ partnorm = await runt.snap.getTagNorm(part)
3162
+ vals.append(partnorm[0])
3163
+
3164
+ return ('.'.join(vals),)
3165
+
3099
3166
  class TagMatch(TagName):
3100
3167
  '''
3101
3168
  Like TagName, but can have asterisks
@@ -3105,6 +3172,32 @@ class TagMatch(TagName):
3105
3172
  # TODO support vars with asterisks?
3106
3173
  return any('*' in kid.valu for kid in self.kids if isinstance(kid, Const))
3107
3174
 
3175
+ async def compute(self, runt, path):
3176
+
3177
+ if self.isconst:
3178
+ return self.constval
3179
+
3180
+ if not isinstance(self.kids[0], Const):
3181
+ valu = await self.kids[0].compute(runt, path)
3182
+ valu = await s_stormtypes.toprim(valu)
3183
+
3184
+ if not isinstance(valu, str):
3185
+ mesg = 'Invalid value type for tag name, tag names must be strings.'
3186
+ raise s_exc.BadTypeValu(mesg=mesg)
3187
+
3188
+ return valu
3189
+
3190
+ vals = []
3191
+ for kid in self.kids:
3192
+ part = await kid.compute(runt, path)
3193
+ if part is None:
3194
+ mesg = f'Null value from var ${kid.name} is not allowed in tag names.'
3195
+ raise s_exc.BadTypeValu(mesg=mesg)
3196
+
3197
+ vals.append(await tostr(part))
3198
+
3199
+ return '.'.join(vals)
3200
+
3108
3201
  class Const(Value):
3109
3202
 
3110
3203
  def __init__(self, astinfo, valu, kids=()):
@@ -3756,27 +3849,15 @@ class EditTagAdd(Edit):
3756
3849
  async for node, path in genr:
3757
3850
 
3758
3851
  try:
3759
- names = await self.kids[oper_offset].compute(runt, path)
3760
- names = await s_stormtypes.toprim(names)
3852
+ names = await self.kids[oper_offset].computeTagArray(runt, path, excignore=excignore)
3761
3853
  except excignore:
3762
3854
  yield node, path
3763
3855
  await asyncio.sleep(0)
3764
3856
  continue
3765
3857
 
3766
- if not isinstance(names, tuple):
3767
- names = (names,)
3768
-
3769
3858
  for name in names:
3770
3859
 
3771
3860
  try:
3772
- if name is None:
3773
- raise self.addExcInfo(s_exc.BadTypeValu(mesg='Null tag names are not allowed.'))
3774
-
3775
- normtupl = await runt.snap.getTagNorm(name)
3776
- if normtupl is None:
3777
- continue
3778
-
3779
- name, info = normtupl
3780
3861
  parts = name.split('.')
3781
3862
 
3782
3863
  runt.layerConfirm(('node', 'tag', 'add', *parts))
@@ -3802,26 +3883,15 @@ class EditTagDel(Edit):
3802
3883
 
3803
3884
  async for node, path in genr:
3804
3885
 
3805
- names = await self.kids[0].compute(runt, path)
3806
- names = await s_stormtypes.toprim(names)
3807
-
3808
- if not isinstance(names, tuple):
3809
- names = (names,)
3886
+ names = await self.kids[0].computeTagArray(runt, path, excignore=(s_exc.BadTypeValu,))
3810
3887
 
3811
3888
  for name in names:
3812
3889
 
3813
- # special case for backward compatibility
3814
- if name:
3815
- normtupl = await runt.snap.getTagNorm(name)
3816
- if normtupl is None:
3817
- continue
3818
-
3819
- name, info = normtupl
3820
- parts = name.split('.')
3890
+ parts = name.split('.')
3821
3891
 
3822
- runt.layerConfirm(('node', 'tag', 'del', *parts))
3892
+ runt.layerConfirm(('node', 'tag', 'del', *parts))
3823
3893
 
3824
- await node.delTag(name)
3894
+ await node.delTag(name)
3825
3895
 
3826
3896
  yield node, path
3827
3897
 
@@ -3847,11 +3917,6 @@ class EditTagPropSet(Edit):
3847
3917
  valu = await self.kids[2].compute(runt, path)
3848
3918
  valu = await s_stormtypes.tostor(valu)
3849
3919
 
3850
- normtupl = await runt.snap.getTagNorm(tag)
3851
- if normtupl is None:
3852
- continue
3853
-
3854
- tag, info = normtupl
3855
3920
  tagparts = tag.split('.')
3856
3921
 
3857
3922
  # for now, use the tag add perms
@@ -3881,13 +3946,6 @@ class EditTagPropDel(Edit):
3881
3946
  async for node, path in genr:
3882
3947
 
3883
3948
  tag, prop = await self.kids[0].compute(runt, path)
3884
-
3885
- normtupl = await runt.snap.getTagNorm(tag)
3886
- if normtupl is None:
3887
- continue
3888
-
3889
- tag, info = normtupl
3890
-
3891
3949
  tagparts = tag.split('.')
3892
3950
 
3893
3951
  # for now, use the tag add perms
synapse/lib/cell.py CHANGED
@@ -884,6 +884,11 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
884
884
  'type': 'object',
885
885
  'hidecmdl': True,
886
886
  },
887
+ 'https:parse:proxy:remoteip': {
888
+ 'description': 'Enable the HTTPS server to parse X-Forwarded-For and X-Real-IP headers to determine requester IP addresses.',
889
+ 'type': 'boolean',
890
+ 'default': False,
891
+ },
887
892
  'backup:dir': {
888
893
  'description': 'A directory outside the service directory where backups will be saved. Defaults to ./backups in the service storage directory.',
889
894
  'type': 'string',
@@ -2584,7 +2589,10 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
2584
2589
 
2585
2590
  sslctx = self.initSslCtx(certpath, pkeypath)
2586
2591
 
2587
- serv = self.wapp.listen(port, address=addr, ssl_options=sslctx)
2592
+ kwargs = {
2593
+ 'xheaders': self.conf.reqConfValu('https:parse:proxy:remoteip')
2594
+ }
2595
+ serv = self.wapp.listen(port, address=addr, ssl_options=sslctx, **kwargs)
2588
2596
  self.httpds.append(serv)
2589
2597
  return list(serv._sockets.values())[0].getsockname()
2590
2598
 
synapse/lib/layer.py CHANGED
@@ -3250,6 +3250,15 @@ class Layer(s_nexus.Pusher):
3250
3250
  oldv, oldt = tp_dict.get(prop, (None, None))
3251
3251
  if oldv is not None:
3252
3252
 
3253
+ if stortype == STOR_TYPE_IVAL:
3254
+ valu = (min(*oldv, *valu), max(*oldv, *valu))
3255
+
3256
+ elif stortype == STOR_TYPE_MINTIME:
3257
+ valu = min(valu, oldv)
3258
+
3259
+ elif stortype == STOR_TYPE_MAXTIME:
3260
+ valu = max(valu, oldv)
3261
+
3253
3262
  if valu == oldv and stortype == oldt:
3254
3263
  return ()
3255
3264
 
synapse/lib/parser.py CHANGED
@@ -56,6 +56,7 @@ terminalEnglishMap = {
56
56
  'EXPRNEG': '-',
57
57
  'EXPRPLUS': '+',
58
58
  'EXPRPOW': '**',
59
+ 'EXPRTAGSEGNOVAR': 'non-variable tag segment',
59
60
  'EXPRTIMES': '*',
60
61
  'FOR': 'for',
61
62
  'FORMATSTRING': 'backtick-quoted format string',
@@ -84,8 +85,8 @@ terminalEnglishMap = {
84
85
  'SETTAGOPER': '?',
85
86
  'SINGLEQUOTEDSTRING': 'single-quoted string',
86
87
  'SWITCH': 'switch',
88
+ 'TAGSEGNOVAR': 'non-variable tag segment',
87
89
  'TRY': 'try',
88
- 'TAGMATCH': 'tag name potentially with asterisks',
89
90
  'TRIPLEQUOTEDSTRING': 'triple-quoted string',
90
91
  'TRYSET': '?=',
91
92
  'TRYSETPLUS': '?+=',
@@ -98,6 +99,7 @@ terminalEnglishMap = {
98
99
  'WHILE': 'while',
99
100
  'WHITETOKN': 'An unquoted string terminated by whitespace',
100
101
  'WILDCARD': '*',
102
+ 'WILDTAGSEGNOVAR': 'tag segment potentially with asterisks',
101
103
  'YIELD': 'yield',
102
104
  '_ARRAYCONDSTART': '*[',
103
105
  '_COLONDOLLAR': ':$',
@@ -111,21 +113,21 @@ terminalEnglishMap = {
111
113
  '_EDGEN2FINI': ')-',
112
114
  '_ELSE': 'else',
113
115
  '_EMBEDQUERYSTART': '${',
116
+ '_EXPRCOLONNOSPACE': ':',
114
117
  '_EMIT': 'emit',
115
118
  '_FINI': 'fini',
116
119
  '_HASH': '#',
117
- '_EXPRHASH': '#',
118
120
  '_HASHSPACE': '#',
119
- '_EXPRHASHSPACE': '#',
120
121
  '_INIT': 'init',
121
122
  '_LEFTJOIN': '<+-',
122
123
  '_LEFTPIVOT': '<-',
123
124
  '_LPARNOSPACE': '(',
125
+ '_MATCHHASH': '#',
126
+ '_MATCHHASHSPACE': '#',
124
127
  '_RETURN': 'return',
125
128
  '_RIGHTJOIN': '-+>',
126
129
  '_RIGHTPIVOT': '->',
127
130
  '_STOP': 'stop',
128
- '_TAGSEGNOVAR': 'tag segment potentially with asterisks',
129
131
  '_WALKNPIVON1': '-->',
130
132
  '_WALKNPIVON2': '<--',
131
133
  '$END': 'end of input',
@@ -404,25 +406,6 @@ class AstConverter(lark.Transformer):
404
406
 
405
407
  return argv
406
408
 
407
- @classmethod
408
- def _tagsplit(cls, astinfo, tag):
409
-
410
- if '$' not in tag:
411
- return [s_ast.Const(astinfo, tag)]
412
-
413
- kids = []
414
- segs = tag.split('.')
415
-
416
- for seg in segs:
417
-
418
- if seg[0] == '$':
419
- kids.append(s_ast.VarValue(astinfo, kids=[s_ast.Const(astinfo, seg[1:])]))
420
- continue
421
-
422
- kids.append(s_ast.Const(astinfo, seg))
423
-
424
- return kids
425
-
426
409
  @lark.v_args(meta=True)
427
410
  def varderef(self, meta, kids):
428
411
  assert kids and len(kids) in (3, 4)
@@ -435,22 +418,6 @@ class AstConverter(lark.Transformer):
435
418
  newkid = self._convert_child(kids[2])
436
419
  return s_ast.VarDeref(astinfo, kids=(kids[0], newkid))
437
420
 
438
- @lark.v_args(meta=True)
439
- def tagname(self, meta, kids):
440
- assert kids and len(kids) == 1
441
- astinfo = self.metaToAstInfo(meta)
442
- kid = kids[0]
443
- if not isinstance(kid, lark.lexer.Token):
444
- return self._convert_child(kid)
445
-
446
- valu = kid.value
447
- if '*' in valu:
448
- mesg = f"Invalid wildcard usage in tag {valu}"
449
- self.raiseBadSyntax(mesg, astinfo)
450
-
451
- kids = self._tagsplit(astinfo, valu)
452
- return s_ast.TagName(astinfo, kids=kids)
453
-
454
421
  @lark.v_args(meta=True)
455
422
  def switchcase(self, meta, kids):
456
423
 
@@ -639,7 +606,6 @@ terminalClassMap = {
639
606
  'HEXNUMBER': lambda astinfo, x: s_ast.Const(astinfo, s_ast.parseNumber(x)),
640
607
  'BOOL': lambda astinfo, x: s_ast.Bool(astinfo, x == 'true'),
641
608
  'SINGLEQUOTEDSTRING': lambda astinfo, x: s_ast.Const(astinfo, x[1:-1]), # drop quotes
642
- 'TAGMATCH': lambda astinfo, x: s_ast.TagMatch(astinfo, kids=AstConverter._tagsplit(astinfo, x)),
643
609
  'NONQUOTEWORD': massage_vartokn,
644
610
  'VARTOKN': massage_vartokn,
645
611
  'EXPRVARTOKN': massage_vartokn,
@@ -734,6 +700,8 @@ ruleClassMap = {
734
700
  'stormcmd': lambda astinfo, kids: s_ast.CmdOper(astinfo, kids=kids if len(kids) == 2 else (kids[0], s_ast.Const(astinfo, tuple()))),
735
701
  'stormfunc': s_ast.Function,
736
702
  'tagcond': s_ast.TagCond,
703
+ 'tagname': s_ast.TagName,
704
+ 'tagmatch': s_ast.TagMatch,
737
705
  'tagprop': s_ast.TagProp,
738
706
  'tagvalu': s_ast.TagValue,
739
707
  'tagpropvalu': s_ast.TagPropValue,
synapse/lib/storm.lark CHANGED
@@ -123,10 +123,10 @@ opervarlist: varlist "=" _valu
123
123
 
124
124
  // Pivots
125
125
  _formpivot: formpivot_pivottotags | formpivot_jointags | formpivot_pivotout | formpivot_
126
- formpivot_pivottotags: _RIGHTPIVOT (ALLTAGS | _tagmatch | _tagmatchwithspace)
127
- formpivot_jointags: _RIGHTJOIN (ALLTAGS | _tagmatch | _tagmatchwithspace)
126
+ formpivot_pivottotags: _RIGHTPIVOT (ALLTAGS | tagmatch)
127
+ formpivot_jointags: _RIGHTJOIN (ALLTAGS | tagmatch)
128
128
  // The special symbol that indicates to pivot to syn:tag nodes
129
- ALLTAGS.2: /#(?=\/[\/\*]|\s|$|\})/
129
+ ALLTAGS.3: /#(?=\/[\/\*]|\s|$|\})/
130
130
 
131
131
  formpivot_pivotout: _RIGHTPIVOT "*"
132
132
  formpivot_: _RIGHTPIVOT ABSPROP
@@ -194,8 +194,6 @@ lifttagtag:(_HASH | _HASHSPACE) tagname [_cmpr _valu]
194
194
  liftbytag: (tagname | tagnamewithspace) [_cmpr _valu]
195
195
  liftbytagprop: (tagprop | tagpropwithspace) [_cmpr _valu]
196
196
  liftbyformtagprop: formtagprop [_cmpr _valu]
197
- tagname: _tagmatch
198
- tagnamewithspace: _tagmatchwithspace -> tagname
199
197
  tagprop: tagname _COLONNOSPACE (BASEPROP | _varvalu)
200
198
  tagpropwithspace: tagnamewithspace _COLONNOSPACE (BASEPROP | _varvalu) -> tagprop
201
199
  formtagprop: ((PROPS | UNIVNAME) | _DEREF _varvalu) tagname _COLONNOSPACE (BASEPROP | _varvalu)
@@ -228,16 +226,20 @@ EQNOSPACE: /(?<!\s)=(?!\s)/
228
226
  cmdrargs: _cmdrargv (EQNOSPACE? _cmdrargv)*
229
227
  _cmdrargv: baresubquery | DOUBLEQUOTEDSTRING | SINGLEQUOTEDSTRING | CMDRTOKN | CMDOPT (EQNOSPACE (CMDRTOKN | SINGLEQUOTEDSTRING | DOUBLEQUOTEDSTRING | baresubquery))?
230
228
 
231
- // A tag with either a variable reference or a tag name potentially with asterisks
232
- _tagmatch: _HASH (_varvalu | TAGMATCH)
229
+ // A tag with either a variable reference or tag name segments without asterisks
230
+ tagname: _HASH (_varvalu | _tagsegs)
231
+ tagnamewithspace: _HASHSPACE (_varvalu | _tagsegs) -> tagname
233
232
  _HASH.2: /(?<!\s)#/
234
-
235
- _tagmatchwithspace: _HASHSPACE (_varvalu | TAGMATCH)
236
233
  _HASHSPACE.2: /(?<=\s)#/
234
+ _tagsegs: TAGSEGNOVAR ( "." (TAGSEGNOVAR | "$" varvalue))*
235
+ TAGSEGNOVAR: /[\w]+/
237
236
 
238
237
  // A tag name with asterisks or $var as segment after the first segment
239
- TAGMATCH: _TAGSEGNOVAR ( "." (_TAGSEGNOVAR | "$" VARTOKN))*
240
- _TAGSEGNOVAR: /[\w*]+/
238
+ tagmatch: (_MATCHHASH | _MATCHHASHSPACE) (_varvalu | _wildtagsegs)
239
+ _MATCHHASH.3: /(?<!\s)#/
240
+ _MATCHHASHSPACE.3: /(?<=\s)#/
241
+ _wildtagsegs: WILDTAGSEGNOVAR ( "." (WILDTAGSEGNOVAR | "$" varvalue))*
242
+ WILDTAGSEGNOVAR: /[\w*]+/
241
243
 
242
244
  // A comparison operator
243
245
  _cmpr: "*" BYNAME | CMPR | CMPROTHER | EQSPACE | EQNOSPACE | TRYSET | SETTAGOPER
@@ -260,9 +262,8 @@ _basevalu: _argvalu | baresubquery
260
262
  _valu: _basevalu | NONQUOTEWORD
261
263
 
262
264
  evalvalu: _valu
263
- exprdict: "{" ((_exprvalu | VARTOKN) ":" (_exprvalu | VARTOKN) ("," (_exprvalu | VARTOKN) ":" (_exprvalu | VARTOKN))* ","? )? "}"
265
+ exprdict: "{" ((_exprvalu | VARTOKN) (":" | _EXPRCOLONNOSPACE) (_exprvalu | VARTOKN) ("," (_exprvalu | VARTOKN) (":" | _EXPRCOLONNOSPACE) (_exprvalu | VARTOKN))* ","? )? "}"
264
266
  exprlist: "[" ((_exprvalu | VARTOKN) ("," (_exprvalu | VARTOKN))* ","? )? "]"
265
-
266
267
  // Just like _valu, but doesn't allow valu lists or unquoted strings or queries
267
268
  _exprvalu: NUMBER | HEXNUMBER | BOOL | exprlist | exprdict | _exprvarvalu | exprrelpropvalu
268
269
  | exprunivpropvalu | exprtagvalu | exprtagpropvalu | TRIPLEQUOTEDSTRING | DOUBLEQUOTEDSTRING
@@ -286,18 +287,17 @@ EXPRUNIVNAME.2: /(?<=^|[\s\|\{\(\[+=-])\.[a-z_][a-z0-9_]*([:.][a-z0-9_]+)*/
286
287
 
287
288
  exprtagvalu: exprtagname -> tagvalu
288
289
  | exprtagnamewithspace -> tagvalu
289
- exprtagname: _exprtagmatch -> tagname
290
- _exprtagmatch: _EXPRHASH (_varvalu | TAGMATCH)
291
- _EXPRHASH.2: /(?<!\s)#/
292
290
 
293
- exprtagnamewithspace: _exprtagmatchwithspace -> tagname
294
- _exprtagmatchwithspace: _EXPRHASHSPACE (_varvalu | TAGMATCH)
295
- _EXPRHASHSPACE.2: /(?<=\s)#/
291
+ exprtagname: _HASH (_exprvarvalu | _exprtagsegs) -> tagname
292
+ exprtagnamewithspace: _HASHSPACE (_exprvarvalu | _exprtagsegs) -> tagname
293
+ _exprtagsegs: EXPRTAGSEGNOVAR ( "." (EXPRTAGSEGNOVAR | "$" exprvarvalue))*
294
+ EXPRTAGSEGNOVAR: /[\w]+/
296
295
 
297
296
  exprtagpropvalu: exprtagprop -> tagpropvalu
298
297
  | exprtagpropwithspace -> tagpropvalu
299
- exprtagprop: exprtagname _COLONNOSPACE (BASEPROP | _exprvarvalu) -> tagprop
300
- exprtagpropwithspace: exprtagnamewithspace _COLONNOSPACE (BASEPROP | _exprvarvalu) -> tagprop
298
+ exprtagprop: exprtagname _EXPRCOLONNOSPACE (BASEPROP | _exprvarvalu) -> tagprop
299
+ exprtagpropwithspace: exprtagnamewithspace _EXPRCOLONNOSPACE (BASEPROP | _exprvarvalu) -> tagprop
300
+ _EXPRCOLONNOSPACE.2: /(?<!\s):/
301
301
 
302
302
  _exprvarvalu: "$" _exprvarvaluatom
303
303
  _exprvarvaluatom: exprvarvalue | exprvarderef | exprfunccall
@@ -372,11 +372,11 @@ relpropvalue: relprop | univprop
372
372
  abspropcond: ABSPROPNOUNIV _cmpr _valu
373
373
  hasabspropcond: ABSPROPNOUNIV
374
374
 
375
- tagpropcond: (tagprop | tagpropwithspace) _cmpr _valu
376
- hastagpropcond: (tagprop | tagpropwithspace)
375
+ tagpropcond: tagmatch _COLONNOSPACE (BASEPROP | _varvalu) _cmpr _valu
376
+ hastagpropcond: tagmatch _COLONNOSPACE (BASEPROP | _varvalu)
377
377
 
378
- tagvalucond: (_tagmatch | _tagmatchwithspace) _cmpr _valu
379
- tagcond: (_tagmatch | _tagmatchwithspace)
378
+ tagvalucond: tagmatch _cmpr _valu
379
+ tagcond: tagmatch
380
380
 
381
381
  condsubq: "{" query "}" [ _cmpr _valu]
382
382
  arraycond: relprop _ARRAYCONDSTART _safe_cmpr _valu "]"
@@ -39,6 +39,7 @@ TerminalPygMap = {
39
39
  'EXPRNEG': p_t.Operator,
40
40
  'EXPRPLUS': p_t.Operator,
41
41
  'EXPRPOW': p_t.Operator,
42
+ 'EXPRTAGSEGNOVAR': p_t.Name,
42
43
  'EXPRTIMES': p_t.Operator,
43
44
  'FOR': p_t.Keyword,
44
45
  'FORMATSTRING': p_t.Literal.String,
@@ -67,7 +68,7 @@ TerminalPygMap = {
67
68
  'SETTAGOPER': p_t.Operator,
68
69
  'SINGLEQUOTEDSTRING': p_t.Literal.String,
69
70
  'SWITCH': p_t.Keyword,
70
- 'TAGMATCH': p_t.Name,
71
+ 'TAGSEGNOVAR': p_t.Name,
71
72
  'TRIPLEQUOTEDSTRING': p_t.Literal.String,
72
73
  'TRYSET': p_t.Operator,
73
74
  'TRYSETMINUS': p_t.Operator,
@@ -80,6 +81,7 @@ TerminalPygMap = {
80
81
  'WHILE': p_t.Keyword,
81
82
  'WHITETOKN': p_t.Literal.String,
82
83
  'WILDCARD': p_t.Name,
84
+ 'WILDTAGSEGNOVAR': p_t.Name,
83
85
  'YIELD': p_t.Keyword,
84
86
  '_ARRAYCONDSTART': p_t.Punctuation,
85
87
  '_COLONDOLLAR': p_t.Punctuation,
@@ -94,20 +96,20 @@ TerminalPygMap = {
94
96
  '_ELSE': p_t.Keyword,
95
97
  '_EMBEDQUERYSTART': p_t.Punctuation,
96
98
  '_EMIT': p_t.Keyword,
99
+ '_EXPRCOLONNOSPACE': p_t.Punctuation,
97
100
  '_FINI': p_t.Keyword,
98
101
  '_HASH': p_t.Punctuation,
99
- '_EXPRHASH': p_t.Punctuation,
100
102
  '_HASHSPACE': p_t.Punctuation,
101
- '_EXPRHASHSPACE': p_t.Punctuation,
102
103
  '_INIT': p_t.Keyword,
103
104
  '_LEFTJOIN': p_t.Punctuation,
104
105
  '_LEFTPIVOT': p_t.Punctuation,
105
106
  '_LPARNOSPACE': p_t.Punctuation,
107
+ '_MATCHHASH': p_t.Punctuation,
108
+ '_MATCHHASHSPACE': p_t.Punctuation,
106
109
  '_RETURN': p_t.Keyword,
107
110
  '_RIGHTJOIN': p_t.Punctuation,
108
111
  '_RIGHTPIVOT': p_t.Punctuation,
109
112
  '_STOP': p_t.Keyword,
110
- '_TAGSEGNOVAR': p_t.Name,
111
113
  '_WALKNPIVON1': p_t.Punctuation,
112
114
  '_WALKNPIVON2': p_t.Punctuation,
113
115
  '$END': p_t.Punctuation,