Skip to content

Commit

Permalink
[eggex] Encode flags to normalized string
Browse files Browse the repository at this point in the history
  • Loading branch information
Andy Chu committed Dec 13, 2023
1 parent 1893841 commit d52d495
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 0 deletions.
24 changes: 24 additions & 0 deletions ysh/regex_translate.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@
re_repeat,
re_repeat_e,
NameType,
EggexFlag,
)
from _devbuild.gen.id_kind_asdl import Id
from _devbuild.gen.value_asdl import value
from core.error import e_die
from frontend import lexer
from mycpp.mylib import log, tagswitch
from osh import glob_ # for ExtendedRegexEscape

Expand Down Expand Up @@ -346,3 +348,25 @@ def AsPosixEre(eggex):
eggex.name_types = name_types

return eggex.as_ere


def _EncodeFlags(flags):
# type: (List[EggexFlag]) -> str
"""
Raises fatal exception on invalid flags.
"""
letters = [] # type: List[str]
for flag in flags:
if flag.negated:
e_die("Flag can't be negated", flag.flag)
flag_name = lexer.TokenVal(flag.flag)
if flag_name in ('i', 'reg_icase'):
letters.append('i')
elif flag_name == 'reg_newline':
letters.append('n')
else:
e_die("Invalid regex flag %r" % flag_name, flag.flag)

# Normalize for comparison
return ''.join(sorted(letters))

51 changes: 51 additions & 0 deletions ysh/regex_translate_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/usr/bin/env python2
from __future__ import print_function

import unittest

from _devbuild.gen.id_kind_asdl import Id
from _devbuild.gen.syntax_asdl import EggexFlag, Token, source, SourceLine

from asdl import runtime
from ysh import regex_translate


def _Name(s):
# Doesn't work
#return lexer.DummyToken(Id.Expr_Name, s)
src = source.Stdin('')
source_line = SourceLine(1, s, src)
return Token(Id.Expr_Name, 0, len(s), runtime.NO_SPID, source_line, None)


class RegexTranslateTest(unittest.TestCase):

def testEncodeFlags(self):
reg_icase = _Name('reg_icase')
i = _Name('i') # abbreviation
reg_newline = _Name('reg_newline')
bad = _Name('bad')

flags = [EggexFlag(False, reg_icase)]
self.assertEqual('i', regex_translate._EncodeFlags(flags))

flags = [EggexFlag(False, i)]
self.assertEqual('i', regex_translate._EncodeFlags(flags))

flags = [EggexFlag(False, bad)]
try:
regex_translate._EncodeFlags(flags)
except Exception as e:
print(e.UserErrorString())
else:
self.fail('Should have failed')

order1 = [EggexFlag(False, reg_icase), EggexFlag(False, reg_newline)]
order2 = [EggexFlag(False, reg_newline), EggexFlag(False, reg_icase)]

self.assertEqual('in', regex_translate._EncodeFlags(order1))
self.assertEqual('in', regex_translate._EncodeFlags(order2))


if __name__ == '__main__':
unittest.main()

0 comments on commit d52d495

Please sign in to comment.