예제 #1
0
               (Keyword("self") + axisOp) |
               (Keyword("descendant-or-self") + axisOp) |
               (Keyword("following-sibling") + axisOp) |
               (Keyword("following") + axisOp) |
               (Keyword("namespace") + axisOp))
forwardStep = ( ( forwardAxis + nodeTest) | abbrevForwardStep )
reverseAxis = ((Keyword("parent") + axisOp) |
               (Keyword("ancestor") + axisOp) |
               (Keyword("preceding-sibling") + axisOp) |
               (Keyword("preceding") + axisOp) |
               (Keyword("ancestor-or-self") + axisOp))
abbrevReverseStep = Literal("..")
reverseStep = ( ( reverseAxis + nodeTest ) | abbrevReverseStep )
step = ( forwardStep | reverseStep )

expr = Forward()
atom = ( 
         ( forOp - (variableRef + inOp + expr).setParseAction(pushRangeVar) + 
                 ZeroOrMore( Suppress(commaOp) + (variableRef + inOp + expr).setParseAction(pushRangeVar) ) - 
                 (returnOp + expr).setParseAction(pushExpr) ).setParseAction(pushOperation) |
         ( quantifiedOp - (variableRef + inOp + expr).setParseAction(pushRangeVar) + 
                 ZeroOrMore( Suppress(commaOp) + (variableRef + inOp + expr ).setParseAction(pushRangeVar) ) - 
                 (satisfiesOp + expr).setParseAction(pushExpr) ).setParseAction(pushOperation) |
         ( (ifOp - Suppress(lParen) + Group(expr) + Suppress(rParen)).setParseAction(pushExpr) - 
           (thenOp + expr).setParseAction(pushOperation) - 
           (elseOp + expr).setParseAction(pushOperation) ).setParseAction(pushOperation) |
         ( qName + Suppress(lParen) + Optional(delimitedList(expr)) + Suppress(rParen) ).setParseAction(pushFunction) |
         ( floatLiteral ).setParseAction(pushFloat) |
         ( decimalLiteral ).setParseAction(pushDecimal) |
         ( integerLiteral ).setParseAction(pushInt) |
         ( quotedString ).setParseAction(pushQuotedString) |
예제 #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
예제 #3
0
def compileCdrGrammar( cntlr, _logMessage ):
    global isGrammarCompiled, cdrProg, lineno

    if isGrammarCompiled:
        return cdrProg
    
    global logMessage
    logMessage = _logMessage
    
    debugParsing = False #  True
    
    cntlr.showStatus(_("Compiling CDR 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, sglQuotedString, delimitedList, Suppress, Regex, FollowedBy,
                     lineno, restOfLine)
    else:
        from pyparsing import (Word, Keyword, alphas, 
                     Literal, CaselessLiteral, 
                     Combine, Optional, nums, Or, Forward, Group, ZeroOrMore, StringEnd, alphanums,
                     ParserElement, sglQuotedString, delimitedList, Suppress, Regex, FollowedBy,
                     lineno, restOfLine)
    
    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
    periodOffset = Regex("-?P[1-3]?[0-9][YQMD](/-[1]?[0-9]-([1-3]?[0-9]|end))?")
    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_.-]*|[*])"
                  ).setName("qName").setDebug(debugParsing)

    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)
    

    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("[")
    rPred  = Literal("]")
    refOp  = Literal("#")
    
    commaOp = Literal(",")
    neOp = Literal("<>")
    leOp = Literal("<=")
    ltOp = Literal("<")
    geOp = Literal(">=")
    gtOp = Literal(">")
    eqOp = Literal("=")
    eqNeOp = eqOp | neOp
    compOp = leOp | ltOp | geOp | gtOp
    plusOp  = Literal("+")
    minusOp = Literal("-")
    plusMinusOp  = plusOp | minusOp
    expOp  = Literal("^")
    multOp  = Literal("*")
    divOp   = Literal("/")
    multDivOp = multOp | divOp
    concatOp  = Literal("&")
    andOp = CaselessLiteral("And")
    orOp = CaselessLiteral("Or")
    xorOp = CaselessLiteral("Xor")
   
    expr = Forward()
    
    atom = ( 
             ( refOp + qName ).setParseAction(compileRefExpression) |
             ( qName + Suppress(lParen) + Optional(delimitedList( expr )) + Suppress(rParen) ).setParseAction(compileFunctionReference) |
             ( qName.setParseAction(compileQname) + lPred + ( periodOffset | ncName) 
                     + rPred).setParseAction(compilePeriodOffsetExpression) |
             ( floatLiteral ).setParseAction(compileFloatLiteral) |
             ( integerLiteral ).setParseAction(compileIntegerLiteral) |
             ( sglQuotedString ).setParseAction(compileStringLiteral) |
             ( qName ).setParseAction(compileQname) |
             ( Suppress(lParen) - expr - Optional( commaOp - Optional( expr - ZeroOrMore( commaOp - expr ) ) ) - Suppress(rParen) ).setParseAction(compileBrackets)
           )
           
    atom.setName("atom").setDebug(debugParsing)
    
    valueExpr = atom
    negationExpr = ( Optional(minusOp) + valueExpr ).setParseAction(compileUnaryOperation)
    expExpr = ( Optional(expOp) + negationExpr ).setParseAction(compileUnaryOperation)
    multDivExpr = ( expExpr + Optional( multDivOp + expExpr ) ).setParseAction(compileBinaryOperation)
    multDivExpr.setName("multDivExpr").setDebug(debugParsing)
    addSubExpr = ( multDivExpr + ZeroOrMore( plusMinusOp + multDivExpr ) ).setParseAction(compileBinaryOperation) 
    addSubExpr.setName("addSubExpr").setDebug(debugParsing)
    concatExpr = ( addSubExpr + ZeroOrMore( concatOp + addSubExpr ) ).setParseAction(compileBinaryOperation) 
    comparisonExpr = ( concatExpr + Optional( compOp + concatExpr ) ).setParseAction(compileBinaryOperation)
    equalityExpr = ( comparisonExpr + Optional( eqNeOp + comparisonExpr ) ).setParseAction(compileBinaryOperation)
    xorExpr = ( equalityExpr + ZeroOrMore( xorOp + equalityExpr) ).setParseAction(compileBinaryOperation)
    andExpr = ( xorExpr + ZeroOrMore( andOp + xorExpr ) ).setParseAction(compileBinaryOperation)
    orExpr = ( andExpr + ZeroOrMore( orOp + andExpr ) ).setParseAction(compileBinaryOperation)
    orExpr.setName("orExpr").setDebug(debugParsing)

    expr << orExpr
    expr.setName("expr").setDebug(debugParsing)
    
    cdrProg = expr + StringEnd()
    expr.setName("cdrProg").setDebug(debugParsing)
    
    startedAt = time.time()
    cntlr.modelManager.showStatus(_("initializing CDR grammar"))
    cdrProg.parseString( "0", parseAll=True )
    from arelle.Locale import format_string
    _msg = format_string(cntlr.modelManager.locale, 
                             _("CDR grammar initialized in %.2f secs"), 
                             time.time() - startedAt)
    logMessage("INFO", "info", _msg)
    cntlr.modelManager.showStatus(_msg, 5000)
    isGrammarCompiled = True

    return cdrProg
예제 #4
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