Example #1
0
# above qName definition allows double :: and excludes non-ascii letters
# qName = Regex("[_A-Za-z\xC0-\xD6\xD8-\xF6\xF8-\xFF\u0100-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]"
#               r"[_\-\."
#               "\xB7A-Za-z0-9\xC0-\xD6\xD8-\xF6\xF8-\xFF\u0100-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u0300-\u036F\u203F-\u2040]*"
#               "[:]?"
#               r"[_\-\."
#               "\xB7A-Za-z0-9\xC0-\xD6\xD8-\xF6\xF8-\xFF\u0100-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u0300-\u036F\u203F-\u2040]*")

ncName = Word(alphas + '_',alphanums + '_-.')
prefixOp = Literal(":")

decimalPoint = Literal('.')
exponentLiteral = CaselessLiteral('e')
plusorminusLiteral = Literal('+') | Literal('-')
digits = Word(nums) 
integerLiteral = Combine( Optional(plusorminusLiteral) + digits )
decimalFractionLiteral = Combine( Optional(plusorminusLiteral) + decimalPoint + digits )
infLiteral = Combine( Optional(plusorminusLiteral) + Literal("INF") )
nanLiteral = Literal("NaN")
floatLiteral = ( Combine( integerLiteral +
                     ( ( decimalPoint + Optional(digits) + exponentLiteral + integerLiteral ) |
                       ( exponentLiteral + integerLiteral ) )
                     ) | 
                 Combine( decimalFractionLiteral + exponentLiteral + integerLiteral ) |
                 infLiteral | nanLiteral ) 
decimalLiteral =  ( Combine( integerLiteral + decimalPoint + Optional(digits) ) |
                    decimalFractionLiteral )


#emptySequence = Literal( "(" ) + Literal( ")" )
lParen  = Literal( "(" )
Example #2
0
def compileSphinxGrammar(cntlr):
    global isGrammarCompiled, sphinxProg, lineno

    if isGrammarCompiled:
        return sphinxProg

    debugParsing = True

    cntlr.showStatus(_("Compiling Sphinx Grammar"))
    if sys.version[0] >= '3':
        # python 3 requires modified parser to allow release of global objects when closing DTS
        from arelle.pyparsing.pyparsing_py3 import (
            Word, Keyword, alphas, Literal, CaselessLiteral, Combine, Optional,
            nums, Or, Forward, Group, ZeroOrMore, StringEnd, alphanums,
            ParserElement, quotedString, delimitedList, Suppress, Regex,
            FollowedBy, lineno)
    else:
        from pyparsing import (Word, Keyword, alphas, Literal, CaselessLiteral,
                               Combine, Optional, nums, Or, Forward, Group,
                               ZeroOrMore, StringEnd, alphanums, ParserElement,
                               quotedString, delimitedList, Suppress, Regex,
                               FollowedBy, lineno)

    ParserElement.enablePackrat()
    """
    the pyparsing parser constructs are defined in this method to prevent the need to compile
    the grammar when the plug in is loaded (which is likely to be when setting up GUI
    menus or command line parser).
    
    instead the grammar is compiled the first time that any sphinx needs to be parsed
    
    only the sphinxExpression (result below) needs to be global for the parser
    """

    # define grammar
    sphinxComment = Regex(
        r"/(?:\*(?:[^*]*\*+)+?/|/[^\n]*(?:\n[^\n]*)*?(?:(?<!\\)|\Z))"
    ).setParseAction(compileComment)

    variableRef = Regex(
        "[$]"  # variable prefix
        # localname part
        "([A-Za-z\xC0-\xD6\xD8-\xF6\xF8-\xFF\u0100-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD_]"
        "[A-Za-z0-9\xC0-\xD6\xD8-\xF6\xF8-\xFF\u0100-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u0300-\u036F\u203F-\u2040\xB7_.-]*)"
    )

    qName = Regex(
        "([A-Za-z\xC0-\xD6\xD8-\xF6\xF8-\xFF\u0100-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD_]"
        "[A-Za-z0-9\xC0-\xD6\xD8-\xF6\xF8-\xFF\u0100-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u0300-\u036F\u203F-\u2040\xB7_.-]*:)?"
        # localname or wildcard-localname part
        "([A-Za-z\xC0-\xD6\xD8-\xF6\xF8-\xFF\u0100-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD_]"
        "[A-Za-z0-9\xC0-\xD6\xD8-\xF6\xF8-\xFF\u0100-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u0300-\u036F\u203F-\u2040\xB7_.-]*|[*])"
    )

    ncName = Regex(
        "([A-Za-z\xC0-\xD6\xD8-\xF6\xF8-\xFF\u0100-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD_]"
        "[A-Za-z0-9\xC0-\xD6\xD8-\xF6\xF8-\xFF\u0100-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u0300-\u036F\u203F-\u2040\xB7_.-]*)"
    ).setName("ncName").setDebug(debugParsing)

    #annotationName = Word("@",alphanums + '_-.').setName("annotationName").setDebug(debugParsing)
    annotationName = Regex(
        "@[A-Za-z\xC0-\xD6\xD8-\xF6\xF8-\xFF\u0100-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD_]\w*"
    ).setName("annotationName").setDebug(debugParsing)

    decimalPoint = Literal('.')
    exponentLiteral = CaselessLiteral('e')
    plusorminusLiteral = Literal('+') | Literal('-')
    digits = Word(nums)
    integerLiteral = Combine(Optional(plusorminusLiteral) + digits)
    decimalFractionLiteral = Combine(
        Optional(plusorminusLiteral) + decimalPoint + digits)
    infLiteral = Combine(Optional(plusorminusLiteral) + Literal("INF"))
    nanLiteral = Literal("NaN")
    floatLiteral = (Combine(integerLiteral + (
        (decimalPoint + Optional(digits) + exponentLiteral + integerLiteral) |
        (exponentLiteral + integerLiteral) |
        (decimalPoint + Optional(digits))))
                    | Combine(decimalFractionLiteral + exponentLiteral +
                              integerLiteral) | decimalFractionLiteral
                    | infLiteral | nanLiteral)

    #emptySequence = Literal( "(" ) + Literal( ")" )
    lParen = Literal("(")
    rParen = Literal(")")
    lPred = Literal("[[") | Literal("[")
    rPred = Literal("]]") | Literal("]")

    commaOp = Literal(",")
    ifOp = Keyword("if")
    elseOp = Keyword("else")
    forOp = Keyword("for")
    inOp = Keyword("in")
    withOp = Keyword("with")
    notOp = Keyword("not")
    valuesOp = Keyword("values")
    andOp = Keyword("and")
    orOp = Keyword("or")
    neOp = Literal("!=")
    leOp = Literal("<=")
    ltOp = Literal("<")
    geOp = Literal(">=")
    gtOp = Literal(">")
    eqOp = Literal("==")
    compOp = leOp | ltOp | geOp | gtOp
    plusOp = Literal("|+|") | Literal("|+") | Literal("+|") | Literal("+")
    minusOp = Literal("|-|") | Literal("|-") | Literal("-|") | Literal("-")
    plusMinusOp = (plusOp | minusOp).setParseAction(compileOp)
    multOp = Literal("*")
    divOp = Literal("/")
    varAssign = Literal("=")
    tagOp = Literal("#")
    asOp = Keyword("as")
    whereOp = Keyword("where")
    wildOp = Literal("**") | Literal("*")
    methodOp = Literal("::")
    formulaOp = Literal(":=")

    namespaceDeclaration = (
        Literal("xmlns") + Optional(Suppress(Literal(":")) + ncName) +
        Suppress(Literal("=")) + quotedString
    ).setParseAction(compileNamespaceDeclaration).ignore(sphinxComment)
    annotationDeclaration = (
        Suppress(Keyword("annotation")) + ncName +
        Optional(Suppress(Keyword("as")) + ncName)
    ).setParseAction(compileAnnotationDeclaration).ignore(sphinxComment)

    packageDeclaration = (
        Suppress(Keyword("package")) +
        ncName).setParseAction(compilePackageDeclaration).ignore(sphinxComment)

    severity = (Suppress(Keyword("severity")) +
                (ncName)).setParseAction(compileSeverity).ignore(sphinxComment)

    expr = Forward()

    atom = ((forOp - Suppress(lParen) - ncName - Suppress(inOp) - expr -
             Suppress(rParen) - expr).setParseAction(compileFor) |
            (ifOp - Suppress(lParen) - expr - Suppress(rParen) - expr -
             Suppress(elseOp) - expr).setParseAction(compileIf) |
            (ncName + Suppress(lParen) + Optional(
                delimitedList(
                    ZeroOrMore((ncName + Optional(tagOp + Optional(ncName)) +
                                varAssign + expr + Suppress(Literal(";"))
                                ).setParseAction(compileVariableAssignment)) +
                    Optional(ncName + varAssign) + expr)) +
             Suppress(rParen)).setParseAction(compileFunctionReference) |
            (floatLiteral).setParseAction(compileFloatLiteral) |
            (integerLiteral).setParseAction(compileIntegerLiteral) |
            (quotedString).setParseAction(compileStringLiteral) |
            (Optional(qName) + lPred + Optional(
                delimitedList(
                    ((whereOp + expr) |
                     ((qName | variableRef) +
                      Optional(tagOp + Optional(ncName)) + Optional(
                          (varAssign + (wildOp | expr) | (inOp + expr) |
                           (asOp + ncName + varAssign + wildOp +
                            Optional(whereOp + expr)))))
                     ).setParseAction(compileHyperspaceAxis),
                    delim=';')) +
             rPred).setParseAction(compileHyperspaceExpression) |
            (variableRef).setParseAction(compileVariableReference) |
            (qName).setParseAction(compileQname) |
            (Suppress(lParen) - expr -
             Optional(commaOp - Optional(expr - ZeroOrMore(commaOp - expr))) -
             Suppress(rParen)).setParseAction(compileBrackets)
            ).ignore(sphinxComment)

    atom.setName("atom").setDebug(debugParsing)

    valueExpr = atom
    taggedExpr = (valueExpr - Optional(tagOp - ncName)
                  ).setParseAction(compileTagAssignment).ignore(sphinxComment)
    methodExpr = (
        (methodOp + ncName + ZeroOrMore(methodOp + taggedExpr)
         ).setParseAction(compileMethodReference) |
        (ZeroOrMore(taggedExpr + methodOp) + taggedExpr)
    ).setParseAction(compileMethodReference).ignore(sphinxComment)
    unaryExpr = (
        Optional(plusMinusOp) +
        methodExpr).setParseAction(compileUnaryOperation).ignore(sphinxComment)
    negateExpr = (
        Optional(notOp) +
        unaryExpr).setParseAction(compileUnaryOperation).ignore(sphinxComment)
    valuesExpr = (Optional(valuesOp) + negateExpr).setParseAction(
        compileValuesIteration).ignore(sphinxComment)
    method2Expr = (valuesExpr +
                   Optional(methodOp + methodExpr)).setParseAction(
                       compileMethodReference).ignore(sphinxComment)
    multiplyExpr = (method2Expr +
                    Optional(multOp + method2Expr)).setParseAction(
                        compileBinaryOperation).ignore(sphinxComment)
    divideExpr = (multiplyExpr +
                  Optional(divOp + multiplyExpr)).setParseAction(
                      compileBinaryOperation).ignore(sphinxComment)
    addExpr = (divideExpr + Optional(plusOp + divideExpr)
               ).setParseAction(compileBinaryOperation).ignore(sphinxComment)
    subtractExpr = (addExpr + Optional(minusOp + addExpr)).setParseAction(
        compileBinaryOperation).ignore(sphinxComment)
    equalityExpr = (subtractExpr +
                    Optional(eqOp + subtractExpr)).setParseAction(
                        compileBinaryOperation).ignore(sphinxComment)
    inequalityExpr = (equalityExpr +
                      Optional(neOp + equalityExpr)).setParseAction(
                          compileBinaryOperation).ignore(sphinxComment)
    comparisonExpr = (inequalityExpr +
                      Optional(compOp + inequalityExpr)).setParseAction(
                          compileBinaryOperation).ignore(sphinxComment)
    andExpr = (comparisonExpr + Optional(andOp + comparisonExpr)
               ).setParseAction(compileBinaryOperation).ignore(sphinxComment)
    orExpr = (andExpr + Optional(orOp + andExpr)
              ).setParseAction(compileBinaryOperation).ignore(sphinxComment)
    formulaExpr = (orExpr + Optional(formulaOp + orExpr)).setParseAction(
        compileBinaryOperation).ignore(sphinxComment)
    withExpr = (Optional(withOp + Suppress(lParen) + expr + Suppress(rParen)) +
                ZeroOrMore(
                    (ncName + Optional(tagOp + Optional(ncName)) + varAssign +
                     expr + Suppress(Literal(";"))).setParseAction(
                         compileVariableAssignment).ignore(sphinxComment)) +
                formulaExpr).setParseAction(compileWith)
    #parsedExpr = withExpr
    #parsedExpr.setName("parsedExpr").setDebug(debugParsing)

    #expr << parsedExpr
    expr << withExpr
    expr.setName("expr").setDebug(debugParsing)

    annotation = (annotationName + Optional(
        Suppress(lParen) + Optional(delimitedList(expr)) +
        Suppress(rParen))).setParseAction(compileAnnotation).ignore(
            sphinxComment).setName("annotation").setDebug(debugParsing)

    constant = (Suppress(Keyword("constant")) + ncName +
                Optional(tagOp + Optional(ncName)) + varAssign +
                expr).setParseAction(compileConstant).ignore(sphinxComment)

    functionDeclaration = (
        (Keyword("function") | Keyword("macro")) + ncName + lParen +
        Optional(delimitedList(ncName)) + rParen +
        expr).setParseAction(compileFunctionDeclaration).ignore(sphinxComment)

    message = (Suppress(Keyword("message")) +
               expr).setParseAction(compileMessage)

    preconditionDeclaration = (
        Suppress(Keyword("precondition")) + ncName + expr + Optional(
            Keyword("otherwise") + Keyword("raise") + ncName +
            Optional(severity) + Optional(message))
    ).setParseAction(compilePreconditionDeclaration).ignore(sphinxComment)

    assignedExpr = (ncName + Optional(tagOp + Optional(ncName)) + varAssign +
                    expr + Suppress(Literal(";"))).setParseAction(
                        compileVariableAssignment).ignore(sphinxComment)

    precondition = (
        Suppress(Keyword("require")) +
        delimitedList(ncName)).setParseAction(compilePrecondition).ignore(
            sphinxComment).setName("precondition").setDebug(debugParsing)

    formulaRule = (Optional(precondition) + Keyword("formula") + ncName +
                   Optional(severity) + Optional((Keyword("bind") + expr)) +
                   ZeroOrMore(assignedExpr) + expr + Optional(message)
                   ).setParseAction(compileFormulaRule).ignore(sphinxComment)
    reportRule = (Optional(precondition) + Keyword("report") + ncName +
                  Optional(severity) + ZeroOrMore(assignedExpr) + expr +
                  Optional(message)
                  ).setParseAction(compileReportRule).ignore(sphinxComment)
    validationRule = (Optional(precondition) + Keyword("raise") + ncName +
                      Optional(severity) + ZeroOrMore(assignedExpr) + expr +
                      Optional(message)).setParseAction(
                          compileValidationRule).ignore(sphinxComment)

    ruleBase = (
        Optional(precondition) + Suppress(Keyword("rule-base")) + ZeroOrMore(
            (Suppress(Keyword("transform")) +
             (Keyword("namespace") + expr + Suppress(Keyword("to")) + expr) |
             (Keyword("qname") + expr + Suppress(Keyword("to")) +
              expr)).setParseAction(compileTransform))
    ).setParseAction(compileRuleBase).ignore(sphinxComment).setName(
        "ruleBase").setDebug(debugParsing)

    sphinxProg = (
        ZeroOrMore(namespaceDeclaration | sphinxComment) +
        ZeroOrMore(annotationDeclaration | annotation | constant
                   | preconditionDeclaration | packageDeclaration
                   | functionDeclaration | ruleBase | formulaRule | reportRule
                   | validationRule | sphinxComment)) + StringEnd()
    sphinxProg.ignore(sphinxComment)

    startedAt = time.time()
    cntlr.modelManager.showStatus(_("initializing sphinx grammar"))
    sphinxProg.parseString("// force initialization\n", parseAll=True)
    from arelle.Locale import format_string
    logMessage(
        "INFO", "info",
        format_string(cntlr.modelManager.locale,
                      _("Sphinx grammar initialized in %.2f secs"),
                      time.time() - startedAt))

    isGrammarCompiled = True

    return sphinxProg