(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) |
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
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
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