Exemplo n.º 1
0
    def __init__(self, ctx):
        self.ctx = ctx

        scripts = set("postrotate prerotate firstaction lastaction preremove".split())
        Stanza = Forward()
        Spaces = Many(WSChar)
        Bare = String(set(string.printable) - (set(string.whitespace) | set("#{}'\"")))
        Num = Number & (WSChar | LineEnd)
        Comment = OneLineComment("#").map(lambda x: None)
        ScriptStart = WS >> PosMarker(Choice([Literal(s) for s in scripts])) << WS
        ScriptEnd = Literal("endscript")
        Line = (WS >> AnyChar.until(EOL) << WS).map(lambda x: "".join(x))
        Lines = Line.until(ScriptEnd | EOF).map(lambda x: "\n".join(x))
        Script = ScriptStart + Lines << Opt(ScriptEnd)
        Script = Script.map(lambda x: [x[0], [x[1]], None])
        BeginBlock = WS >> LeftCurly << WS
        EndBlock = WS >> RightCurly
        First = PosMarker((Bare | QuotedString)) << Spaces
        Attr = Spaces >> (Num | Bare | QuotedString) << Spaces
        Rest = Many(Attr)
        Block = BeginBlock >> Many(Stanza).map(skip_none).map(self.to_entries) << EndBlock
        Stmt = WS >> (Script | (First + Rest + Opt(Block))) << WS
        Stanza <= WS >> (Stmt | Comment) << WS
        Doc = Many(Stanza).map(skip_none).map(self.to_entries)

        self.Top = Doc << EOF
Exemplo n.º 2
0
    def __init__(self, ctx):
        self.ctx = ctx

        Complex = Forward()
        Comment = (WS >> OneLineComment("#")).map(lambda x: None)

        Name = String(string.ascii_letters + "_/")
        Num = Number & (WSChar | LineEnd)

        StartName = WS >> PosMarker(StartTagName(Letters)) << WS
        EndName = WS >> EndTagName(Letters, ignore_case=True) << WS

        Cont = Char("\\") + EOL
        AttrStart = Many(WSChar)
        AttrEnd = (Many(WSChar) + Cont) | Many(WSChar)

        OpAttr = (Literal("!=") | Literal("<=") | Literal(">=")
                  | InSet("<>")) & WSChar
        BareAttr = String(
            set(string.printable) - (set(string.whitespace) | set("<>'\"")))
        Attr = AttrStart >> (Num | QuotedString | OpAttr | BareAttr) << AttrEnd
        Attrs = Many(Attr)

        StartTag = (WS + LT) >> (StartName + Attrs) << (GT + WS)
        EndTag = (WS + LT + FS) >> EndName << (GT + WS)

        Simple = WS >> (Lift(self.to_directive) * PosMarker(Name) *
                        Attrs) << WS
        Stanza = Simple | Complex | Comment | Many(WSChar | EOL,
                                                   lower=1).map(lambda x: None)
        Complex <= (Lift(self.to_section) * StartTag *
                    Many(Stanza).map(skip_none)) << EndTag
        Doc = Many(Stanza).map(skip_none)

        self.Top = Doc + EOF
Exemplo n.º 3
0
def parse_doc(content, ctx):
    def to_directive(x):
        name, rest = x
        rest = [rest] if rest is not None else []
        return Directive(name=name.value.strip(),
                         attrs=rest,
                         lineno=name.lineno,
                         src=ctx)

    def to_section(name, rest):
        return Section(name=name.value.strip(),
                       children=rest,
                       lineno=name.lineno,
                       src=ctx)

    def apply_defaults(cfg):
        if "DEFAULT" not in cfg:
            return cfg

        defaults = cfg["DEFAULT"]
        not_defaults = cfg[~eq("DEFAULT")]
        for c in not_defaults:
            for d in defaults.grandchildren:
                if d.name not in c:
                    c.children.append(d)

        cfg.children = list(not_defaults)
        return cfg

    header_chars = (set(string.printable) - set(string.whitespace) -
                    set("[]")) | set(" ")
    sep_chars = set("=:")
    key_chars = header_chars - sep_chars
    value_chars = set(string.printable) - set("\n\r")

    Yes = Literal("yes", True, ignore_case=True)
    No = Literal("no", False, ignore_case=True)
    Tru = Literal("true", True, ignore_case=True)
    Fals = Literal("false", False, ignore_case=True)
    Boolean = ((Yes | No | Tru | Fals) & (WSChar | LineEnd)) % "Boolean"

    LeftEnd = (WS + LeftBracket + WS)
    RightEnd = (WS + RightBracket + WS)
    Header = (
        LeftEnd >> PosMarker(String(header_chars)) << RightEnd) % "Header"
    Key = WS >> PosMarker(String(key_chars)) << WS
    Sep = InSet(sep_chars, "Sep")
    Value = WS >> (Boolean | HangingString(value_chars))
    KVPair = WithIndent(Key + Opt(Sep >> Value)) % "KVPair"
    Comment = (WS >>
               (OneLineComment("#") | OneLineComment(";")).map(lambda x: None))

    Line = Comment | KVPair.map(to_directive)
    Sect = Lift(to_section) * Header * Many(Line).map(skip_none)
    Doc = Many(Comment | Sect).map(skip_none)
    Top = Doc + EOF

    res = Entry(children=Top(content)[0], src=ctx)
    return apply_defaults(res)
Exemplo n.º 4
0
def parse_doc(f, ctx=None, line_end="\n"):
    def to_entry(name, rest):
        if isinstance(rest, list):
            return Section(name=name.value,
                           children=rest,
                           lineno=name.lineno,
                           src=ctx)
        return Directive(name=name.value,
                         attrs=[rest],
                         lineno=name.lineno,
                         src=ctx)

    Sep = InSet(":=")
    Stmt = Forward()
    Num = Number & (WSChar | LineEnd)
    NULL = Literal("none", value=None)
    Comment = (WS >> OneLineComment("#").map(lambda x: None))
    BeginBlock = (WS >> LeftCurly << WS)
    EndBlock = (WS >> RightCurly << WS)
    Bare = String(
        set(string.printable) - (set(string.whitespace) | set("#{}'\"")))
    Name = WS >> PosMarker(
        String(string.ascii_letters + "_" + string.digits)) << WS
    Value = WS >> (Num | NULL | QuotedString | Bare) << WS
    Block = BeginBlock >> Many(Stmt).map(skip_none) << EndBlock
    Stanza = (Lift(to_entry) * Name * (Block | (Sep >> Value))) | Comment
    Stmt <= WS >> Stanza << WS
    Doc = Many(Stmt).map(skip_none)
    Top = Doc + EOF

    return Entry(children=Top(f)[0], src=ctx)
Exemplo n.º 5
0
    def parse_doc(self, content):
        try:
            def to_directive(x):
                name, rest = x
                rest = [rest] if rest is not None else []
                return Directive(name=name.value.strip(), attrs=rest, lineno=name.lineno, src=self)

            def to_section(name, rest):
                return Section(name=name.value.strip(), children=rest, lineno=name.lineno, src=self)

            def apply_defaults(cfg):
                if "DEFAULT" not in cfg:
                    return cfg

                defaults = cfg["DEFAULT"]
                not_defaults = cfg[~eq("DEFAULT")]
                for c in not_defaults:
                    for d in defaults.grandchildren:
                        if d.name not in c:
                            c.children.append(d)

                cfg.children = list(not_defaults)
                return cfg

            def make_bytes(number, char_multiple):
                if char_multiple.lower() == 'k':
                    return number * 2**10
                if char_multiple.lower() == 'm':
                    return number * 2**20
                if char_multiple.lower() == 'g':
                    return number * 2**30

            content = "\n".join(content)

            header_chars = (set(string.printable) - set(string.whitespace) - set("[]")) | set(" ")
            sep_chars = set("=")
            key_chars = header_chars - sep_chars
            value_chars = set(string.printable) - set("\n\r")

            On = Literal("on", True, ignore_case=True)
            Off = Literal("off", False, ignore_case=True)
            Tru = Literal("true", True, ignore_case=True)
            Fals = Literal("false", False, ignore_case=True)
            Boolean = ((On | Off | Tru | Fals) & (WSChar | LineEnd)) % "Boolean"
            Num = Number & (WSChar | LineEnd)
            QuoStr = QuotedString & (WSChar | LineEnd)
            # Handle php.ini shorthand notation for memory limits: 1G, 8M, 50K
            # https://www.php.net/manual/en/faq.using.php#faq.using.shorthandbytes
            MemNum = (Lift(make_bytes) * Number * (Char('K') | Char('M') | Char('G'))) & (WSChar | LineEnd)

            LeftEnd = (WS + LeftBracket + WS)
            RightEnd = (WS + RightBracket + WS)
            Header = (LeftEnd >> PosMarker(String(header_chars)) << RightEnd) % "Header"
            Key = WS >> PosMarker(String(key_chars)) << WS
            Sep = InSet(sep_chars, "Sep")
            Value = WS >> (Boolean | MemNum | Num | QuoStr | HangingString(value_chars))
            KVPair = WithIndent(Key + Opt(Sep >> Value)) % "KVPair"
            Comment = (WS >> (OneLineComment(";")).map(lambda x: None))

            Line = Comment | KVPair.map(to_directive)
            Sect = Lift(to_section) * Header * Many(Line).map(skip_none)
            Doc = Many(Comment | Sect).map(skip_none)
            Top = Doc << WS << EOF

            res = Entry(children=Top(content), src=self)
            return apply_defaults(res)

        except SkipException:
            raise
        except:
            raise ParseException(ParseException("Could not parse content: '{0}'".
                                                format(content)))
Exemplo n.º 6
0
def loads(data):
    return Entry(children=Top(data))


def load(f):
    return loads(f.read())


def to_entry(name, rest):
    if isinstance(rest, list):
        return Section(name=name.value, children=rest, lineno=name.lineno)
    return Directive(name=name.value, attrs=[rest], lineno=name.lineno)


Sep = InSet(":=")
Stmt = Forward()
Num = Number & (WSChar | LineEnd)
NULL = Literal("none", value=None)
Comment = (WS >> OneLineComment("#").map(lambda x: None))
BeginBlock = (WS >> LeftCurly << WS)
EndBlock = (WS >> RightCurly << WS)
Bare = String(set(string.printable) - (set(string.whitespace) | set("#{}'\"")))
Name = WS >> PosMarker(
    String(string.ascii_letters + "_" + string.digits)) << WS
Value = WS >> (Num | NULL | QuotedString | Bare) << WS
Block = BeginBlock >> Many(Stmt).map(skip_none) << EndBlock
Stanza = (Lift(to_entry) * Name * (Block | (Sep >> Value))) | Comment
Stmt <= WS >> Stanza << WS
Doc = Many(Stmt).map(skip_none)
Top = Doc << EOF
Exemplo n.º 7
0
def test_literal_value():
    p = Literal("true", value=True)
    assert p("true") is True
Exemplo n.º 8
0
def test_literal():
    p = Literal("123")
    assert p("123") == "123"
Exemplo n.º 9
0
def test_literal_value_ignore_case():
    p = Literal("true", value=True, ignore_case=True)
    assert p("TRUE") is True
Exemplo n.º 10
0
def test_literal_ignore_case():
    p = Literal("true", ignore_case=True)
    assert p("TrUe") == "TrUe"
Exemplo n.º 11
0
def test_forward():
    true = Forward()
    true <= Literal("True", value=True)
    assert true("True")
Exemplo n.º 12
0
json_parser handles primitive json parsing. It doesn't handle unicode or
numbers in scientific notation.
"""
from insights.parsr import (Colon, Comma, EOF, Forward, Literal, LeftBracket,
                            LeftCurly, Number, RightBracket, RightCurly,
                            QuotedString, WS)


def loads(data):
    return Top(data)[0]


def load(f):
    return loads(f.read())


JsonArray = Forward()
JsonObject = Forward()
TRUE = Literal("true", value=True)
FALSE = Literal("false", value=False)
NULL = Literal("null", value=None)
SimpleValue = (Number | QuotedString | JsonObject | JsonArray | TRUE | FALSE
               | NULL)
JsonValue = (WS >> SimpleValue << WS)
Key = (QuotedString << Colon)
KVPairs = (((WS >> Key) + JsonValue).sep_by(Comma))
JsonArray <= (LeftBracket >> JsonValue.sep_by(Comma) << RightBracket)
JsonObject <= (LeftCurly >> KVPairs.map(lambda res: dict(
    (k, v) for (k, v) in res)) << RightCurly)
Top = JsonValue + EOF
Exemplo n.º 13
0
            for n in [name.value] + attrs:
                ret.append(Section(name=n, children=body, lineno=name.lineno))
        else:
            attrs = [attrs] if not isinstance(attrs, list) else attrs
            ret.append(
                Directive(name=name.value, attrs=attrs, lineno=name.lineno))
    return ret


scripts = set("postrotate prerotate firstaction lastaction preremove".split())
Stanza = Forward()
Spaces = Many(WSChar)
Bare = String(set(string.printable) - (set(string.whitespace) | set("#{}'\"")))
Num = Number & (WSChar | LineEnd)
Comment = OneLineComment("#").map(lambda x: None)
ScriptStart = WS >> PosMarker(Choice([Literal(s) for s in scripts])) << WS
ScriptEnd = Literal("endscript")
Line = (WS >> AnyChar.until(EOL) << WS).map(lambda x: "".join(x))
Lines = Line.until(ScriptEnd).map(lambda x: "\n".join(x))
Script = ScriptStart + Lines << ScriptEnd
Script = Script.map(lambda x: [x[0], x[1], None])
BeginBlock = WS >> LeftCurly << WS
EndBlock = WS >> RightCurly
First = PosMarker((Bare | QuotedString)) << Spaces
Attr = Spaces >> (Num | Bare | QuotedString) << Spaces
Rest = Many(Attr)
Block = BeginBlock >> Many(Stanza).map(skip_none).map(to_entries) << EndBlock
Stmt = WS >> (Script | (First + Rest + Opt(Block))) << WS
Stanza <= WS >> (Stmt | Comment) << WS
Doc = Many(Stanza).map(skip_none).map(to_entries)
Top = Doc + EOF