XPath/XPointer grammar parser. This software is in Public Domain. IT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND. Please send bug reports and comments to<EMAIL_ADDRESS>Kirill Lisovsky<EMAIL_ADDRESS>Dmitry Lizorkin
For building a specific XPath/XPointer implementation, grammar parser is to be parameterized txp-params ::= (listof txp-param ) txp-param ::= (list param-name param-value [parameterized-func] ) parameterized-func is optional Each parser-param generally specifies the parser result for the single XPath/XPointer grammar rule
Given param-name, returns the corresponding lambda
There are 2 kinds of errors: syntactic errors and semantic errors - Syntactic error is raised when the location path (fragment identifier) doesn't satisfy XPath (XPointer) grammar. Syntactic error is discovered and raised by the parser. - Semantic error can be raised by the specific parser parametrization
Whether a parser returns an error
A warning message for grammar features which are not supported by this implementation
To signal the parser about the semantic error, the specific parametrization is to return the symbol 'txp:semantic-error
Constructed specific parsers may wish to use this function
XPath location path (XPointer fragment identifier) is represented as a list of chars
A list of whitespace characters
A sxml:whitespace or () <> [] : / + * , = | ! " ' @ $
A list of characters a NCName cannot start with
The function reads a whitespace , production [3] (S) in XML Rec. path - xpointer path string as a list of chars It returns a new path
Asserts that the path is over, possibly with trailing whitespace symbols at the end. Returns the boolean value - whether assertion passes. If assertion fails, signals an error message
Whether the path begins with a 'str' (starting whitespaces are ignored) str - a string to match path - an xpointer path represented as a list of chars char-list - an optional argument. If this argument is supplied, a 'str' pattern must be followed by a character from a 'char-list' If 'str' is really in the beginning of path, a new path is returned Otherwise, function returns #f (path remains unchanged)
Checks whether the PATH starts with a sequence of strings (possibly separated by a whitespace) from STR-SEQ Returns a new PATH (match successful) or #f (otherwise)
Similar to the 'parse-check' function. But this function also has a side effect. It displays an error message if the 'str' doesn't match the beginning of 'path'.
Reads a NCName, taking into account that whitespaces and characters: ( ) < > [ ] : / + * , = | ! " ' @ $ may not be used in it. Moreover, its first character can't be: . - or a digit The result: (list ncname new-path) or #f ncname - NCName represented as a string If there is no NCName in the current position of the path, then an error message is displayed and #f is returned
Reads a Name production. It is similar to a 'parse-ncname' function. The only difference is that #\: is allowed within a Name
The function reads a qualified name (QName) Returns: ( (prefix . local-part) new-path ) or ( local-part new-path ) if there is no prefix if there is not QName in the beginning of the 'path' it calls sxml:xpointer-parse-error prefix, local-part - strings new-path - a list of characters
Reads a natural number: [1-9] [0-9]* The result: (list number new-path) or #f
Reads a Literal ([29] in XPath specification) [29] Literal ::= '"' [^"]* '"' | "'" [^']* "'" The result: (string new-path) or #f
Reads a Number ([30]-[31] in XPath specification) [30] Number ::= Digits ('.' Digits?)? | '.' Digits [31] Digits ::= [0-9]+ The result: (number new-path) or #f
Produces a parameterized parser txp-params - a long associative list of parameters which specify handlers for different grammar rules. Precise content for 'txp-params' is discussed iteratively in comments within function's body. However, 'txp-params' are currently intended for TXPath developers only and are thus documented very briefly The function returns an associative list: (list (list 'xpath xpath-implementation-res) (list 'xpointer xpointer-implementation-res) (list 'expr xpath-expression-implementation-res)) xpath-implementation-res - XPath implementation produced, as was conducted by 'txp-params' xpointer-implementation-res - XPointer implementation produced (for XPointer grammar from W3C Candidate Recommendation 11 September 2001), as was conducted by 'txp-params' xpath-expression-implementation-res - implementation for XPath Expr grammar production NOTE: Future versions of this function may include additional members to the associative list which is returned as the result
Given param-name, returns the corresponding lambda
(define (txp:param-value param-name txp-params) (cond ((assq param-name txp-params) => cadr) (else (display "Parameter unspecified: ") (display param-name) 0 ; this would cause program termination )))
Whether a parser returns an error
(define (txp:error? obj) (or (eq? obj 'txp:parser-error) (eq? obj 'txp:semantic-error)))
A list of whitespace characters
(define sxml:whitespace '(#\space #\return #\newline #\tab))
A sxml:whitespace or () <> [] : / + * , = | ! " ' @ $
(define sxml:delimiter (append sxml:whitespace '(#\( #\) #\< #\> #\[ #\] #\: #\/ #\+ #\* #\, #\= #\| #\! #\" #\' #\@ #\$)))
A list of characters a NCName cannot start with
(define (sxml:non-first? ch) (or (char-numeric? ch) (memv ch sxml:delimiter) (memv ch '(#\. #\-))))
The function reads a whitespace , production [3] (S) in XML Rec. path - xpointer path string as a list of chars It returns a new path
(define (sxml:skip-ws path) (if (or (null? path) (not (memv (car path) sxml:whitespace))) path (sxml:skip-ws (cdr path))))
Asserts that the path is over, possibly with trailing whitespace symbols at the end. Returns the boolean value - whether assertion passes. If assertion fails, signals an error message
(define (sxml:assert-end-of-path path) (let ((path (sxml:skip-ws path))) (or (null? path) (begin (sxml:xpointer-parse-error "unexpected - \"" (list->string path) "\"") #f))))
Produces a parameterized parser txp-params - a long associative list of parameters which specify handlers for different grammar rules. Precise content for 'txp-params' is discussed iteratively in comments within function's body. However, 'txp-params' are currently intended for TXPath developers only and are thus documented very briefly The function returns an associative list: (list (list 'xpath xpath-implementation-res) (list 'xpointer xpointer-implementation-res) (list 'expr xpath-expression-implementation-res)) xpath-implementation-res - XPath implementation produced, as was conducted by 'txp-params' xpointer-implementation-res - XPointer implementation produced (for XPointer grammar from W3C Candidate Recommendation 11 September 2001), as was conducted by 'txp-params' xpath-expression-implementation-res - implementation for XPath Expr grammar production NOTE: Future versions of this function may include additional members to the associative list which is returned as the result
(define (txp:parameterize-parser txp-params) (letrec ( ; All these functions have similar arguments: ; path - an xpath location path represented as a list of chars ; ns-binding - declared namespace prefixes (not for all functions) ; ns-binding = (listof (prefix . uri)) ; prefix - symbol, uri - string ;------------------------------------------------- ; Functions which parse XPath grammar ; Parses an AxisSpecifier production ([5],[6],[13] in XPath specification) ; [5] AxisSpecifier ::= AxisName '::' ; | AbbreviatedAxisSpecifier ; [6] AxisName ::= 'ancestor' ; | 'ancestor-or-self' ; | 'attribute' ; | 'child' ; | 'descendant' ; | 'descendant-or-self' ; | 'following' ; | 'following-sibling' ; | 'namespace' ; | 'parent' ; | 'preceding' ; | 'preceding-sibling' ; | 'self' ; [13] AbbreviatedAxisSpecifier ::= '@'? ; ; txp-params are to include the following parameter: ; param-name = 'axis ; param-value = ; (list (list 'ancestor (lambda (add-on) ...) ) ; (list 'ancestor-or-self (lambda (add-on) ...) ) ; (list 'attribute (lambda (add-on) ...) ) ; ...) ; the remaining axes in the same manner (txp:parse-axis-specifier (let* ((axis-param-value (txp:param-value 'axis txp-params)) (child-impl (txp:param-value 'child axis-param-value)) (parser-pairs (cons `(("@") ,(txp:param-value 'attribute axis-param-value)) (map (lambda (single-pair) (list (list (symbol->string (car single-pair)) "::") (cadr single-pair))) axis-param-value)))) (lambda (path ns-binding add-on) ; ns-binding is dummy here (let loop ((pairs parser-pairs)) (cond ((null? pairs) ; a default (child) axis (list (child-impl add-on) path)) ((sxml:parse-check-sequence (caar pairs) path) => (lambda (path) (list ((cadar pairs) add-on) path))) (else ; continue loop (loop (cdr pairs)))))))) ; Parses a NodeTest production ; ([7],[37] in XPath specification, [11] in XPointer specification) ; [7] NodeTest ::= NameTest ; | NodeType '(' ')' ; | 'processing-instruction' '(' Literal ')' ; [37] NameTest ::= '*' ; | NCName ':' '*' ; | QName ; [11] NodeType ::= 'comment' ; | 'text' ; | 'processing-instruction' ; | 'node' ; | 'point' ; | 'range' ; ; txp-params are to include the following parameter: ; param-name ::= 'node-test ; param-value ::= ; (list (list 'star (lambda (add-on) ...) ) ; (list 'uri+star (lambda (uri add-on) ...) ) ; (list 'qname (lambda (uri local-name add-on) ...) ) ; (list 'comment (lambda (add-on) ...) ) ; (list 'text (lambda (add-on) ...) ) ; (list 'processing-instruction ; (lambda (literal-string add-on) ...) ) ; (list 'node (lambda (add-on) ...) ) ; (list 'point (lambda (add-on) ...) ) ; (list 'range (lambda (add-on) ...) )) ; uri - a string or #f (the latter is possible for 'qname only) ; local-name - a string ; literal - a string (txp:parse-node-test (let* ((ntest-param-value (txp:param-value 'node-test txp-params)) (star-impl (txp:param-value 'star ntest-param-value)) (uri+star-impl (txp:param-value 'uri+star ntest-param-value)) (qname-impl (txp:param-value 'qname ntest-param-value)) (comment-impl (txp:param-value 'comment ntest-param-value)) (text-impl (txp:param-value 'text ntest-param-value)) (pi-impl (txp:param-value 'processing-instruction ntest-param-value)) (node-impl (txp:param-value 'node ntest-param-value)) (point-impl (txp:param-value 'point ntest-param-value)) (range-impl (txp:param-value 'range ntest-param-value)) (brackets (lambda (path) (and-let* ((path (sxml:parse-assert "(" path))) (sxml:parse-assert ")" path))))) (lambda (path ns-binding add-on) (cond ((sxml:parse-check-sequence '("comment" "(") path) => (lambda (path) (and-let* ((path (sxml:parse-assert ")" path))) (list (comment-impl add-on) path)))) ((sxml:parse-check-sequence '("text" "(") path) => (lambda (path) (and-let* ((path (sxml:parse-assert ")" path))) (list (text-impl add-on) path)))) ((sxml:parse-check-sequence '("node" "(") path) => (lambda (path) (and-let* ((path (sxml:parse-assert ")" path))) (list (node-impl add-on) path)))) ((sxml:parse-check-sequence '("processing-instruction" "(") path) => (lambda (path) (cond ((sxml:parse-check ")" path) => (lambda (path) (list (pi-impl #f add-on) path))) (else (and-let* ((lst (sxml:parse-literal path)) (name (car lst)) (path (sxml:parse-assert ")" (cadr lst)))) (list (pi-impl name add-on) path)))))) ((sxml:parse-check-sequence '("point" "(") path) => (lambda (path) (and-let* ((path (sxml:parse-assert ")" path))) (list (point-impl add-on) path)))) ((sxml:parse-check-sequence '("range" "(") path) => (lambda (path) (and-let* ((path (sxml:parse-assert ")" path))) (list (range-impl add-on) path)))) ((sxml:parse-check "*" path) => (lambda (path) (list (star-impl add-on) path))) (else ; NCName ':' '*' | QName (and-let* ((lst (sxml:parse-ncname path))) (let ((path (cadr lst))) (if (or (null? path) (not (char=? (car path) #\:))) ; local name (list (qname-impl #f (car lst) add-on) path) (let* ((name (string->symbol (car lst))) (path (sxml:parse-assert ":" path)) (pair (assq name ns-binding))) (cond ((not pair) (sxml:xpointer-parse-error "unknown namespace prefix - " name)) ((and (not (null? path)) (char=? (car path) #\*)) (list (uri+star-impl (cdr pair) add-on) (sxml:parse-assert "*" path))) (else (and-let* ((lst (sxml:parse-ncname path))) (list (qname-impl (cdr pair) (car lst) add-on) (cadr lst)))))))))))))) ; Parses a Step production ; ([4xptr] in XPointer specification, [12] in XPath specification) ; [4xptr] Step ::= AxisSpecifier NodeTest Predicate* ; | AbbreviatedStep ; | 'range-to' '(' Expr ')' Predicate* ; [12] AbbreviatedStep ::= '.' ; | '..' ; ; txp-params are to include the following parameter: ; param-name ::= 'step ; param-value ::= ; (list ; (list 'common ; (lambda (axis-res node-test-res predicate-res-lst add-on) ...) ) ; (list 'range-to ; (lambda (expr-res predicate-res-lst add-on) ...) )) (txp:parse-step (let* ((step-param-value (txp:param-value 'step txp-params)) (common-value (txp:param-value 'common step-param-value)) (range-to-value (txp:param-value 'range-to step-param-value)) (axis-param-value (txp:param-value 'axis txp-params)) (self-value (txp:param-value 'self axis-param-value)) (parent-value (txp:param-value 'parent axis-param-value)) (ntest-param-value (txp:param-value 'node-test txp-params)) (node-value (txp:param-value 'node ntest-param-value))) (lambda (path ns-binding add-on) (cond ((sxml:parse-check ".." path) (list (common-value (parent-value add-on) (node-value add-on) '() add-on) (sxml:parse-assert ".." path))) ((sxml:parse-check "." path) (list (common-value (self-value add-on) (node-value add-on) '() add-on) (sxml:parse-assert "." path))) ((sxml:parse-check "range-to" path) (and-let* ((path0 (sxml:parse-assert "(" (sxml:parse-assert "range-to" path))) (lst (txp:parse-expr path0 ns-binding add-on)) (path (sxml:parse-assert ")" (cadr lst)))) (let ((expr-res (car lst))) (let loop ((path path) (pred-lst '())) (if (sxml:parse-check "[" path) (and-let* ((lst (txp:parse-predicate path ns-binding add-on))) (loop (cadr lst) (cons (car lst) pred-lst))) ; Predicates are over (list (if (apply txp:semantic-errs-detected? (cons expr-res pred-lst)) 'txp:semantic-error (range-to-value expr-res (reverse pred-lst) add-on)) path)))))) (else ; common implementation (and-let* ((lst (txp:parse-axis-specifier path ns-binding add-on))) (let ((axis (car lst))) (and-let* ((lst (txp:parse-node-test (cadr lst) ns-binding add-on))) (let ((test (car lst))) (let loop ((preds '()) (path (cadr lst))) (if (sxml:parse-check "[" path) (and-let* ((lst (txp:parse-predicate path ns-binding add-on))) (loop (cons (car lst) preds) (cadr lst))) ; No more predicates (list (if (or (txp:semantic-errs-detected? axis test) (apply txp:semantic-errs-detected? preds)) 'txp:semantic-error (common-value axis test (reverse preds) add-on)) path)))))))))))) ; Parses a RelativeLocationPath production ([3],[11] in ; XPath specification) ; [3] RelativeLocationPath ::= Step ; | RelativeLocationPath '/' Step ; | AbbreviatedRelativeLocationPath ; [11] AbbreviatedRelativeLocationPath ::= ; RelativeLocationPath '//' Step ; ; txp-params are to include the following parameter: ; param-name ::= 'relative-lpath ; param-value ::= (lambda (step-res-lst add-on) ...) (txp:parse-relative-location-path (let* ((relative-lpath-value (txp:param-value 'relative-lpath txp-params)) (step-param-value (txp:param-value 'step txp-params)) (common-value (txp:param-value 'common step-param-value)) (axis-param-value (txp:param-value 'axis txp-params)) (descendant-or-self-value (txp:param-value 'descendant-or-self axis-param-value)) (ntest-param-value (txp:param-value 'node-test txp-params)) (node-value (txp:param-value 'node ntest-param-value))) (lambda (path ns-binding add-on) (let loop ((step-res-lst '()) (path path)) (and-let* ((lst (txp:parse-step path ns-binding add-on))) (let ((step-res (car lst)) (path (cadr lst))) (cond ((sxml:parse-check "//" path) (loop (cons ; // = /descendant-or-self::node()/ (common-value (descendant-or-self-value add-on) (node-value add-on) '() add-on) (cons step-res step-res-lst)) (sxml:parse-assert "//" path))) ((sxml:parse-check "/" path) (loop (cons step-res step-res-lst) (sxml:parse-assert "/" path))) (else ; no more steps (list (if (apply txp:semantic-errs-detected? step-res-lst) 'txp:semantic-error (relative-lpath-value (reverse (cons step-res step-res-lst)) add-on)) path))))))))) ; Parses a LocationPath production ([1],[2],[10] in XPath specification) ; [1] LocationPath ::= RelativeLocationPath ; | AbsoluteLocationPath ; [2] AbsoluteLocationPath ::= '/' RelativeLocationPath? ; | AbbreviatedAbsoluteLocationPath ; [10] AbbreviatedAbsoluteLocationPath ::= ; '//' RelativeLocationPath ; ; txp-params are to include the following parameter: ; param-name ::= 'location-path ; param-value ::= ; (list ; (list 'bare-slash (lambda (add-on) ...) ) ; (list 'slash (lambda (relative-lpath-res add-on) ...) ) ; (list 'double-slash (lambda (relative-lpath-res add-on) ...) )) (txp:parse-location-path (let* ((location-path-value (txp:param-value 'location-path txp-params)) (bare-slash-value (txp:param-value 'bare-slash location-path-value)) (slash-value (txp:param-value 'slash location-path-value)) (double-slash-value (txp:param-value 'double-slash location-path-value)) (nothing? ; whether no relative location path follows '/' (lambda (path) (let ((path (sxml:skip-ws path))) (cond ((null? path) #t) ((memv (car path) '(#\| #\+ #\- #\< #\> #\= #\) #\] #\,)) #t) ((or (sxml:parse-check "mod" path sxml:delimiter) (sxml:parse-check "div" path sxml:delimiter) (sxml:parse-check "!=" path) (sxml:parse-check "and" path sxml:delimiter) (sxml:parse-check "or" path sxml:delimiter)) #t) (else #f)))))) (lambda (path ns-binding add-on) (cond ((sxml:parse-check "//" path) (and-let* ((lst (txp:parse-relative-location-path (sxml:parse-assert "//" path) ns-binding add-on))) (let ((relative-res (car lst)) (path (cadr lst))) (list (if (txp:semantic-errs-detected? relative-res) 'txp:semantic-error (double-slash-value relative-res add-on)) path)))) ((sxml:parse-check "/" path) => (lambda (path) (if (nothing? path) (list (bare-slash-value add-on) path) (and-let* ((lst (txp:parse-relative-location-path path ns-binding add-on))) (let ((relative-res (car lst)) (path (cadr lst))) (list (if (txp:semantic-errs-detected? relative-res) 'txp:semantic-error (slash-value relative-res add-on)) path)))))) (else ; Location path is a Relative location path (txp:parse-relative-location-path path ns-binding add-on)))))) ; Parses a Predicate production ([8]-[9] in XPath specification) ; [8] Predicate ::= '[' PredicateExpr ']' ; [9] PredicateExpr ::= Expr ; ; txp-params are to include the following parameter: ; param-name ::= 'predicate ; param-value ::= (lambda (expr-res add-on) ...) (txp:parse-predicate (let ((predicate-value (txp:param-value 'predicate txp-params))) (lambda (path ns-binding add-on) (and-let* ((path0 (sxml:parse-assert "[" path)) (lst (txp:parse-expr path0 ns-binding add-on)) (path (sxml:parse-assert "]" (cadr lst)))) (list (if (txp:semantic-errs-detected? (car lst)) 'txp:semantic-error (predicate-value (car lst) add-on)) path))))) ; Parses a VariableReference production ([36] in XPath specification) ; [36] VariableReference ::= '$' QName ; ; txp-params are to include the following parameter: ; param-name ::= 'variable-ref ; param-value ::= (lambda (var-name-string add-on) ...) (txp:parse-variable-reference (let ((var-ref-value (txp:param-value 'variable-ref txp-params))) (lambda (path ns-binding add-on) (and-let* ((path (sxml:parse-assert "$" path)) (lst (sxml:parse-qname path))) (let ((name (if (pair? (car lst)) ; contains a prefix-part (string-append (caar lst) ":" (cdar lst)) (car lst)))) (list (var-ref-value name add-on) (cadr lst))))))) ; Parses a FunctionCall production ([16],[17],[35] in ; XPath specification) ; [16] FunctionCall ::= FunctionName ; '(' ( Argument ( ',' Argument )* )? ')' ; [17] Argument ::= Expr ; [35] FunctionName ::= QName - NodeType ; ; txp-params are to include the following parameter: ; param-name ::= 'function-call ; param-value ::= (lambda (fun-name-string arg-res-lst add-on) ...) ; ; NOTE: prefix resolution for qualified function names not implemented (txp:parse-function-call (let ((fun-call-value (txp:param-value 'function-call txp-params)) (parse-arguments ; Returns (list (listof arg-res) new-path) (lambda (path ns-binding add-on) (and-let* ((path (sxml:parse-assert "(" path))) (cond ((sxml:parse-check ")" path) => (lambda (path) (list '() path))) (else (let single-arg ((arg-res-lst '()) (path path)) (and-let* ((lst (txp:parse-expr path ns-binding add-on))) (let ((arg-res (car lst)) (path (cadr lst))) (cond ((sxml:parse-check ")" path) => (lambda (path) (list (reverse (cons arg-res arg-res-lst)) path))) (else (and-let* ((path (sxml:parse-assert "," path))) (single-arg (cons arg-res arg-res-lst) path))))))))))))) (lambda (path ns-binding add-on) (and-let* ((lst (sxml:parse-qname path))) (let ((fun-name (car lst))) ; can be a pair (and-let* ((lst (parse-arguments (cadr lst) ns-binding add-on))) (let ((arg-res-lst (car lst)) (path (cadr lst))) (list (if (apply txp:semantic-errs-detected? arg-res-lst) 'txp:semantic-error (fun-call-value (if (pair? fun-name) ; a prefix and a local part (string-append (car fun-name) ":" (cdr fun-name)) fun-name) arg-res-lst add-on)) path)))))))) ; Parses a PrimaryExpr production ([15] in XPath specification) ; [15] PrimaryExpr ::= VariableReference ; | '(' Expr ')' ; | Literal ; | Number ; | FunctionCall ; [29] Literal ::= '"' [^"]* '"' ; | "'" [^']* "'" ; [30] Number ::= Digits ('.' Digits?)? ; | '.' Digits ; [31] Digits ::= [0-9]+ ; ; txp-params are to include the following parameter: ; param-name ::= 'primary-expr ; param-value ::= ; (list (list 'literal (lambda (literal add-on) ...) ) ; (list 'number (lambda (number add-on) ...) )) (txp:parse-primary-expr (let* ((primary-expr-value (txp:param-value 'primary-expr txp-params)) (literal-value (txp:param-value 'literal primary-expr-value)) (number-value (txp:param-value 'number primary-expr-value))) (lambda (path ns-binding add-on) (cond ((sxml:parse-check "$" path) ; a VariableReference (txp:parse-variable-reference path ns-binding add-on)) ((sxml:parse-check "(" path) ; an '(' Expr ')' (and-let* ((lst (txp:parse-expr (sxml:parse-assert "(" path) ns-binding add-on)) (path (sxml:parse-assert ")" (cadr lst)))) (let ((expr-res (car lst))) (list expr-res path)))) ((or (sxml:parse-check "\"" path) (sxml:parse-check "'" path)) ; a Literal (and-let* ((lst (sxml:parse-literal path))) (list (literal-value (car lst) add-on) (cadr lst)))) ((let ((p (sxml:skip-ws path))) ; a Number? (cond ((null? p) #f) ((char=? (car p) #\.) #t) ((and (char>=? (car p) #\0) (char<=? (car p) #\9)) #t) (else #f))) (and-let* ((lst (sxml:parse-number path))) (list (number-value (car lst) add-on) (cadr lst)))) (else ; a Function call (txp:parse-function-call path ns-binding add-on)))))) ; Parses a FilterExpr production ([20] in XPath specification) ; [20] FilterExpr ::= PrimaryExpr ; | FilterExpr Predicate ; ; txp-params are to include the following parameter: ; param-name ::= 'filter-expr ; param-value ::= ; (lambda (primary-expr-res predicate-res-lst add-on) ...) ) (txp:parse-filter-expr (let ((filter-expr-value (txp:param-value 'filter-expr txp-params))) (lambda (path ns-binding add-on) (and-let* ((lst (txp:parse-primary-expr path ns-binding add-on))) (let ((prim-res (car lst))) (let loop ((pred-res-lst '()) (path (cadr lst))) (cond ((sxml:parse-check "[" path) (and-let* ((lst (txp:parse-predicate path ns-binding add-on))) (loop (cons (car lst) pred-res-lst) (cadr lst)))) ; No more predicates ((null? pred-res-lst) (list prim-res path)) (else (list (if (apply txp:semantic-errs-detected? (cons prim-res pred-res-lst)) 'txp:semantic-error (filter-expr-value prim-res (reverse pred-res-lst) add-on)) path))))))))) ; Parses a PathExpr production ([19] in XPath specification) ; [19] PathExpr ::= LocationPath ; | FilterExpr ; | FilterExpr '/' RelativeLocationPath ; | FilterExpr '//' RelativeLocationPath ; ; txp-params are to include the following parameter: ; param-name ::= 'path-expr ; param-value ::= ; (list ; (list 'slash ; (lambda (filter-expr-res relative-lpath-res add-on) ...) ) ; (list 'double-slash ; (lambda (filter-expr-res relative-lpath-res add-on) ...) )) (txp:parse-path-expr (let ((filter-expr? (lambda (path) (let ((path (sxml:skip-ws path))) (cond ((null? path) #f) ((member (car path) '(#\$ #\( #\" #\' #\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9)) #t) ((char=? (car path) #\.) (cond ((null? (cdr path)) #f) ((member (cadr path) '(#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9)) #t) (else #f))) ((member (car path) '(#\) #\< #\> #\[ #\] #\/ #\+ #\* #\, #\= #\| #\! #\@ #\-)) #f) (else (let ((lst (sxml:parse-ncname path))) (cond ((not lst) #f) ((sxml:parse-check "::" (cadr lst)) #f) (else (and-let* ((lst (sxml:parse-name path))) (let ((name (car lst)) (new-path (sxml:skip-ws (cadr lst)))) (cond ((string=? name "range-to") #f) ((string=? name "comment") #f) ((string=? name "text") #f) ((string=? name "processing-instruction") #f) ((string=? name "node") #f) ((string=? name "point") #f) ((string=? name "range") #f) ((null? new-path) #f) ((char=? (car new-path) #\() #t) (else #f))))))))))))) (let* ((path-expr-value (txp:param-value 'path-expr txp-params)) (slash-value (txp:param-value 'slash path-expr-value)) (double-slash-value (txp:param-value 'double-slash path-expr-value))) (lambda (path ns-binding add-on) (if (not (filter-expr? path)) (txp:parse-location-path path ns-binding add-on) (and-let* ((lst (txp:parse-filter-expr path ns-binding add-on))) (let ((filter-ex-res (car lst)) (path (cadr lst))) (cond ((sxml:parse-check "//" path) (and-let* ((lst2 (txp:parse-relative-location-path (sxml:parse-assert "//" path) ns-binding add-on))) (let ((rel-lpath-res (car lst2)) (path (cadr lst2))) (list (if (txp:semantic-errs-detected? filter-ex-res rel-lpath-res) 'txp:semantic-error (double-slash-value filter-ex-res rel-lpath-res add-on)) path)))) ((sxml:parse-check "/" path) (and-let* ((lst2 (txp:parse-relative-location-path (sxml:parse-assert "/" path) ns-binding add-on))) (let ((rel-lpath-res (car lst2)) (path (cadr lst2))) (list (if (txp:semantic-errs-detected? filter-ex-res rel-lpath-res) 'txp:semantic-error (slash-value filter-ex-res rel-lpath-res add-on)) path)))) (else ; A single filter expression, not followed by lpath lst))))))))) ; Parses a UnionExpr production ([18] in XPath specification) ; [18] UnionExpr ::= PathExpr ; | UnionExpr '|' PathExpr ; ; txp-params are to include the following parameter: ; param-name ::= 'union-expr ; param-value ::= (lambda (path-expr-res-lst add-on) ...) (txp:parse-union-expr (let ((union-expr-value (txp:param-value 'union-expr txp-params))) (lambda (path ns-binding add-on) (let loop ((p-e-res-lst '()) (path path)) (and-let* ((lst (txp:parse-path-expr path ns-binding add-on))) (let ((p-e-res (car lst)) (path (cadr lst))) (let ((new-path (sxml:parse-check "|" path))) (cond (new-path ; more PathExprs (loop (cons p-e-res p-e-res-lst) new-path)) ; no more PathExprs ((null? p-e-res-lst) ; only one PathExpr (list p-e-res path)) (else ; several Path-exprs (list (if (apply txp:semantic-errs-detected? (cons p-e-res p-e-res-lst)) 'txp:semantic-error (union-expr-value (reverse (cons p-e-res p-e-res-lst)) add-on)) path)))))))))) ; Parses a UnaryExpr production ([27] in XPath specification) ; [27] UnaryExpr ::= UnionExpr ; | '-' UnaryExpr ; Note that the grammar allows multiple unary minuses ; ; txp-params are to include the following parameter: ; param-name ::= 'unary-expr ; param-value ::= (lambda (union-expr-res num-minuses add-on) ...) (txp:parse-unary-expr (let ((unary-expr-value (txp:param-value 'unary-expr txp-params))) (lambda (path ns-binding add-on) (if (not (sxml:parse-check "-" path)) (txp:parse-union-expr path ns-binding add-on) (let loop ((num-minuses 0) (path path)) (let ((new-path (sxml:parse-check "-" path))) (if new-path ; more minuses (loop (+ num-minuses 1) new-path) (and-let* ((lst (txp:parse-union-expr path ns-binding add-on))) (let ((union-expr-res (car lst)) (path (cadr lst))) (list (if (txp:semantic-errs-detected? union-expr-res) 'txp:semantic-error (unary-expr-value union-expr-res num-minuses add-on)) path)))))))))) ; Parses a MultiplicativeExpr production ([26],[34] in ; XPath specification) ; [26] MultiplicativeExpr ::= ; UnaryExpr ; | MultiplicativeExpr MultiplyOperator UnaryExpr ; | MultiplicativeExpr 'div' UnaryExpr ; | MultiplicativeExpr 'mod' UnaryExpr ; [34] MultiplyOperator ::= '*' ; ; txp-params are to include the following parameter: ; param-name ::= 'mul-expr ; param-value ::= (lambda (unary-expr-res-lst op-lst add-on) ...) (txp:parse-multiplicative-expr (let* ((mul-expr-value (txp:param-value 'mul-expr txp-params)) (operations-value (txp:param-value 'operations txp-params)) (multiply-value (txp:param-value '* operations-value)) (div-value (txp:param-value 'div operations-value)) (mod-value (txp:param-value 'mod operations-value))) (lambda (path ns-binding add-on) (let loop ((unary-expr-res-lst '()) (op-lst '()) (path path)) (and-let* ((lst (txp:parse-unary-expr path ns-binding add-on))) (let ((unary-expr-res (car lst)) (path (cadr lst))) (cond ((sxml:parse-check "*" path) (loop (cons unary-expr-res unary-expr-res-lst) (cons (multiply-value add-on) op-lst) (sxml:parse-assert "*" path))) ((sxml:parse-check "div" path sxml:delimiter) (loop (cons unary-expr-res unary-expr-res-lst) (cons (div-value add-on) op-lst) (sxml:parse-assert "div" path))) ((sxml:parse-check "mod" path sxml:delimiter) (loop (cons unary-expr-res unary-expr-res-lst) (cons (mod-value add-on) op-lst) (sxml:parse-assert "mod" path))) ; no more UnaryExprs ((null? unary-expr-res-lst) ; single UnaryExpr lst) (else ; several UnaryExprs (list (if (apply txp:semantic-errs-detected? (cons unary-expr-res unary-expr-res-lst)) 'txp:semantic-error (mul-expr-value (reverse (cons unary-expr-res unary-expr-res-lst)) (reverse op-lst) add-on)) path))))))))) ; Parses a AdditiveExpr production ([25] in XPath specification) ; [25] AdditiveExpr ::= MultiplicativeExpr ; | AdditiveExpr '+' MultiplicativeExpr ; | AdditiveExpr '-' MultiplicativeExpr ; ; txp-params are to include the following parameter: ; param-name ::= 'add-expr ; param-value ::= (lambda (mul-expr-res-lst op-lst add-on) ...) (txp:parse-additive-expr (let* ((add-expr-value (txp:param-value 'add-expr txp-params)) (operations-value (txp:param-value 'operations txp-params)) (plus-value (txp:param-value '+ operations-value)) (minus-value (txp:param-value '- operations-value))) (lambda (path ns-binding add-on) (let loop ((mul-expr-res-lst '()) (op-lst '()) (path path)) (and-let* ((lst (txp:parse-multiplicative-expr path ns-binding add-on))) (let ((mul-expr-res (car lst)) (path (cadr lst))) (cond ((sxml:parse-check "+" path) (loop (cons mul-expr-res mul-expr-res-lst) (cons (plus-value add-on) op-lst) (sxml:parse-assert "+" path))) ((sxml:parse-check "-" path) (loop (cons mul-expr-res mul-expr-res-lst) (cons (minus-value add-on) op-lst) (sxml:parse-assert "-" path))) ; no more MultiplicativeExprs ((null? mul-expr-res-lst) ; single MultiplicativeExpr lst) (else ; several MultiplicativeExprs (list (if (apply txp:semantic-errs-detected? (cons mul-expr-res mul-expr-res-lst)) 'txp:semantic-error (add-expr-value (reverse (cons mul-expr-res mul-expr-res-lst)) (reverse op-lst) add-on)) path))))))))) ; Parses a RelationalExpr production ([24] in XPath specification) ; [24] RelationalExpr ::= AdditiveExpr ; | RelationalExpr '<' AdditiveExpr ; | RelationalExpr '>' AdditiveExpr ; | RelationalExpr '<=' AdditiveExpr ; | RelationalExpr '>=' AdditiveExpr ; ; txp-params are to include the following parameter: ; param-name ::= 'relational-expr ; param-value ::= ; (lambda (additive-expr-res-lst cmp-op-lst add-on) ...) (txp:parse-relational-expr (let* ((rel-expr-value (txp:param-value 'relational-expr txp-params)) (operations-value (txp:param-value 'operations txp-params)) (ls-value (txp:param-value '< operations-value)) (gt-value (txp:param-value '> operations-value)) (le-value (txp:param-value '<= operations-value)) (ge-value (txp:param-value '>= operations-value))) (lambda (path ns-binding add-on) (let loop ((add-res-lst '()) (cmp-op-lst '()) (path path)) (and-let* ((lst (txp:parse-additive-expr path ns-binding add-on))) (let ((add-res (car lst)) (path (cadr lst))) (cond ((sxml:parse-check "<=" path) (loop (cons add-res add-res-lst) (cons (le-value add-on) cmp-op-lst) (sxml:parse-assert "<=" path))) ((sxml:parse-check ">=" path) (loop (cons add-res add-res-lst) (cons (ge-value add-on) cmp-op-lst) (sxml:parse-assert ">=" path))) ((sxml:parse-check "<" path) (loop (cons add-res add-res-lst) (cons (ls-value add-on) cmp-op-lst) (sxml:parse-assert "<" path))) ((sxml:parse-check ">" path) (loop (cons add-res add-res-lst) (cons (gt-value add-on) cmp-op-lst) (sxml:parse-assert ">" path))) ; no more AdditiveExprs ((null? add-res-lst) ; single AdditiveExpr lst) (else ; several AdditiveExprs (list (if (apply txp:semantic-errs-detected? (cons add-res add-res-lst)) 'txp:semantic-error (rel-expr-value (reverse (cons add-res add-res-lst)) (reverse cmp-op-lst) add-on)) path))))))))) ; Parses an EqualityExpr production ([23] in XPath specification) ; [23] EqualityExpr ::= RelationalExpr ; | EqualityExpr '=' RelationalExpr ; | EqualityExpr '!=' RelationalExpr ; ; txp-params are to include the following parameter: ; param-name ::= 'equality-expr ; param-value ::= ; (lambda (relational-expr-res-lst cmp-op-lst add-on) ...) (txp:parse-equality-expr (let* ((equality-expr-value (txp:param-value 'equality-expr txp-params)) (operations-value (txp:param-value 'operations txp-params)) (equal-value (txp:param-value '= operations-value)) (not-equal-value (txp:param-value '!= operations-value))) (lambda (path ns-binding add-on) (let loop ((rel-res-lst '()) (cmp-op-lst '()) (path path)) (and-let* ((lst (txp:parse-relational-expr path ns-binding add-on))) (let ((rel-res (car lst)) (path (cadr lst))) (cond ((sxml:parse-check "=" path) (loop (cons rel-res rel-res-lst) (cons (equal-value add-on) cmp-op-lst) (sxml:parse-assert "=" path))) ((sxml:parse-check "!=" path) (loop (cons rel-res rel-res-lst) (cons (not-equal-value add-on) cmp-op-lst) (sxml:parse-assert "!=" path))) ; no more RelationalExprs ((null? rel-res-lst) ; only one RelationalExpr lst) (else ; several RelationalExprs (list (if (apply txp:semantic-errs-detected? (cons rel-res rel-res-lst)) 'txp:semantic-error (equality-expr-value (reverse (cons rel-res rel-res-lst)) (reverse cmp-op-lst) add-on)) path))))))))) ; Parses an AndExpr production ([22] in XPath specification) ; [22] AndExpr ::= EqualityExpr ; | AndExpr 'and' EqualityExpr ; Note that according to 3.4 in XPath specification, the right operand ; is not evaluated if the left operand evaluates to false ; ; txp-params are to include the following parameter: ; param-name ::= 'and-expr ; param-value ::= (lambda (equality-expr-res-lst add-on) ...) (txp:parse-and-expr (let ((and-expr-value (txp:param-value 'and-expr txp-params))) (lambda (path ns-binding add-on) (let loop ((equality-res-lst '()) (path path)) (and-let* ((lst (txp:parse-equality-expr path ns-binding add-on))) (let ((equality-res (car lst)) (path (cadr lst))) (let ((new-path (sxml:parse-check "and" path sxml:delimiter))) (cond (new-path (loop (cons equality-res equality-res-lst) new-path)) ; no more EqualityExprs ((null? equality-res-lst) ; only one EqualityExpr lst) (else ; several EqualityExprs (list (if (apply txp:semantic-errs-detected? (cons equality-res equality-res-lst)) 'txp:semantic-error (and-expr-value (reverse (cons equality-res equality-res-lst)) add-on)) path)))))))))) ; Parses an Expr production ([14],[21] in XPath specification) ; [14] Expr ::= OrExpr ; [21] OrExpr ::= AndExpr ; | OrExpr 'or' AndExpr ; Note that according to 3.4 in XPath specification, the right operand ; is not evaluated if the left operand evaluates to true ; ; txp-params are to include the following parameter: ; param-name ::= 'or-expr ; param-value ::= (lambda (and-expr-res-lst add-on) ...) (txp:parse-expr (let ((or-expr-value (txp:param-value 'or-expr txp-params))) (lambda (path ns-binding add-on) (let loop ((and-res-lst '()) (path path)) (and-let* ((lst (txp:parse-and-expr path ns-binding add-on))) (let ((and-res (car lst)) (path (cadr lst))) (let ((new-path (sxml:parse-check "or" path sxml:delimiter))) (cond (new-path (loop (cons and-res and-res-lst) new-path)) ; no more AndExprs ((null? and-res-lst) ; only one AndExpr lst) (else ; several AndExprs (list (if (apply txp:semantic-errs-detected? (cons and-res and-res-lst)) 'txp:semantic-error (or-expr-value (reverse (cons and-res and-res-lst)) add-on)) path)))))))))) ;------------------------------------------------ ; Functions which parse XPointer grammar ; Parses an FullXPtr production ([3]-[10] in XPointer specification) ; [3] FullXPtr ::= XPtrPart (S? XPtrPart)* ; [4] XPtrPart ::= 'xpointer' '(' XPtrExpr ')' ; | 'xmlns' '(' XPtrNsDecl? ')' ; | Scheme '(' SchemeSpecificExpr ')' ; [5] Scheme ::= NCName ; [6] SchemeSpecificExpr ::= StringWithBalancedParens ; [7] StringWithBalancedParens ::= ; [^()]* ('(' StringWithBalancedParens ')' [^()]*)* ; [8] XPtrExpr ::= Expr ; [9] XPtrNsDecl ::= NCName S? '=' S? XPtrNsURI ; [10] XPtrNsURI ::= Char* ; ; txp-params are to include the following parameter: ; param-name ::= 'full-xptr ; param-value ::= (lambda (expr-res-lst add-on) ...) (txp:parse-full-xptr (let ((full-xptr-value (txp:param-value 'full-xptr txp-params))) (lambda (path ns-binding add-on) (let loop ((expr-res-lst '()) (ns-binding ns-binding) (path path)) (if (null? (sxml:skip-ws path)) ; the string is over (cond ((= (length expr-res-lst) 1) ; a single XPointer part (car expr-res-lst)) ((apply txp:semantic-errs-detected? expr-res-lst) 'txp:semantic-error) (else (full-xptr-value (reverse expr-res-lst) add-on))) (and-let* ((lst (sxml:parse-name path)) (name (car lst)) (path (cadr lst))) (cond ((string=? name "xpointer") ; xpointer part (and-let* ((path (sxml:parse-assert "(" path)) (lst2 (txp:parse-expr path ns-binding add-on))) (let ((expr-res (car lst2)) (path (cadr lst2))) (and-let* ((path (sxml:parse-assert ")" path))) (loop (cons expr-res expr-res-lst) ns-binding path))))) ((string=? name "xmlns") ; xmlns part (and-let* ((path0 (sxml:parse-assert "(" path)) (lst2 (sxml:parse-ncname path0)) (prefix (string->symbol (car lst2))) (path (sxml:parse-assert "=" (cadr lst2)))) (let rpt2 ((path (sxml:skip-ws path)) (uri '())) (cond ((null? path) (sxml:parse-assert ")" path) #f) ((and (char=? (car path) #\)) (null? uri)) (sxml:xpointer-parse-error "namespace URI cannot be empty")) ((char=? (car path) #\)) (loop expr-res-lst (cons (cons prefix (list->string (reverse uri))) ns-binding) (cdr path))) (else (rpt2 (cdr path) (cons (car path) uri))))))) (else ; any other XPointer scheme (and-let* ((path (sxml:parse-assert "(" path))) (let rpt3 ((n 1) (path path)) (cond ((= n 0) (sxml:xpointer-parse-warning "unknown xpointer schema - " name ". Ignoring") (loop expr-res-lst ns-binding path)) ((null? path) (sxml:parse-assert ")" path) #f) ((char=? (car path) #\() (rpt3 (+ n 1) (cdr path))) ((char=? (car path) #\)) (rpt3 (- n 1) (cdr path))) (else (rpt3 n (cdr path)))))))))))))) ; Parses an ChildSeq production ([2] in XPointer specification) ; [2] ChildSeq ::= Name? ('/' [1-9] [0-9]* )+ ; ; txp-params are to include the following parameter: ; param-name ::= 'child-seq ; param-value ::= ; (list ; (list 'with-name ; (lambda (name-string number-lst add-on) ...) ) ; (list 'without-name ; (lambda (number-lst add-on) ...) )) (txp:parse-child-seq (let ((helper (lambda (path) (let loop ((num-lst '()) (path path)) (let ((path2 (sxml:parse-check "/" path))) (cond (path2 ; #\/ found (and-let* ((lst (sxml:parse-natural path2))) (loop (cons (car lst) num-lst) (cadr lst)))) ((null? (sxml:skip-ws path)) ; end of path (reverse num-lst)) (else ; this will cause an error message (sxml:parse-assert "/" path)))))))) (let* ((child-seq-value (txp:param-value 'child-seq txp-params)) (with-name-value (txp:param-value 'with-name child-seq-value)) (without-name-value (txp:param-value 'without-name child-seq-value))) (lambda (path ns-binding add-on) (let ((path2 (sxml:parse-check "/" path))) (if path2 ; "/" found => no Name supported (and-let* ((number-lst (helper path))) (without-name-value number-lst add-on)) (and-let* ((lst (sxml:parse-name path)) (name (car lst)) (number-lst (helper (cadr lst)))) (with-name-value name number-lst add-on)))))))) ;------------------------------------------------- ; Higher level functions ; ns-binding - declared namespace prefixes (an optional argument) ; add-on - whatever; may be useful for specific parser ; implementations, since this parameter is passed throughout all ; grammar rules ; ; ns-binding = (listof (prefix . uri)) ; prefix - a symbol ; uri - a string ; Parses XPath grammar ; path is a string here (txp:parse-xpath (lambda (path-string ns-binding add-on) (let ((res (txp:parse-location-path (string->list path-string) ns-binding add-on))) (if (and res ; no parser errors (sxml:assert-end-of-path (cadr res))) (car res) 'txp:parser-error)))) ; Parses an XPointer production ([1] in XPointer specification) ; [1] XPointer ::= Name | ChildSeq | FullXPtr (txp:parse-xpointer (lambda (path-string ns-binding add-on) (let ((path (string->list path-string))) (if (sxml:parse-check "/" path) ; => ChildSeq (txp:parse-child-seq path ns-binding add-on) (and-let* ((lst (sxml:parse-name path)) (new-path (cadr lst))) (if (sxml:parse-check "(" new-path) ; FullXPtr production (txp:parse-full-xptr path ns-binding add-on) (txp:parse-child-seq path ns-binding add-on))))))) ; Parses XPath Expression ; [14] Expr ::= OrExpr (txp:parse-xpath-expression (lambda (path-string ns-binding add-on) (let ((res (txp:parse-expr (string->list path-string) ns-binding add-on))) (if (and res ; no parser errors (sxml:assert-end-of-path (cadr res))) (car res) 'txp:parser-error)))) ) `((xpath ,txp:parse-xpath) (xpointer ,txp:parse-xpointer) (expr ,txp:parse-xpath-expression)) ))
(define (sxml:xpointer-parse-error . text) (apply cerr (append (list "XPath/XPointer parser error: ") text (list nl))) #f)
A warning message for grammar features which are not supported by this implementation
(define (sxml:xpointer-parse-warning . text) (apply cerr (append (list "XPointer parser warning: ") text (list nl))))
(define (txp:semantic-errs-detected? . res-list) (not (null? (filter (lambda (res) (eq? res 'txp:semantic-error)) res-list))))
Constructed specific parsers may wish to use this function
(define (txp:signal-semantic-error . text) (apply cerr (append (list "XPath/XPointer semantic error: ") text (list nl))) 'txp:semantic-error)
Whether the path begins with a 'str' (starting whitespaces are ignored) str - a string to match path - an xpointer path represented as a list of chars char-list - an optional argument. If this argument is supplied, a 'str' pattern must be followed by a character from a 'char-list' If 'str' is really in the beginning of path, a new path is returned Otherwise, function returns #f (path remains unchanged)
(define (sxml:parse-check str path . char-list) (let loop ((lst (string->list str)) (p (sxml:skip-ws path))) (cond ((null? lst) (if (or (null? p) (null? char-list) (memv (car p) (car char-list))) p #f)) ((null? p) #f) ((char=? (car lst) (car p)) (loop (cdr lst) (cdr p))) (else #f))))
Checks whether the PATH starts with a sequence of strings (possibly separated by a whitespace) from STR-SEQ Returns a new PATH (match successful) or #f (otherwise)
(define (sxml:parse-check-sequence str-seq path . char-list) (let ((char-list (if (null? char-list) #f (car char-list)))) (let loop ((str-seq str-seq) (path path)) (cond ((null? str-seq) path) ; successful match ((if char-list (sxml:parse-check (car str-seq) path char-list) (sxml:parse-check (car str-seq) path)) => (lambda (new-path) (loop (cdr str-seq) new-path))) (else #f))))) ; unsuccessful match
Similar to the 'parse-check' function. But this function also has a side effect. It displays an error message if the 'str' doesn't match the beginning of 'path'.
(define (sxml:parse-assert str path) (let loop ((lst (string->list str)) (p (sxml:skip-ws path))) (cond ((null? lst) p) ((null? p) (sxml:xpointer-parse-error "unexpected end of XPointer path. " "Expected - \"" str "\", given - \"" (list->string path) "\"")) ((char=? (car lst) (car p)) (loop (cdr lst) (cdr p))) (else (sxml:xpointer-parse-error "expected - \"" str "\", given - \"" (list->string path) "\"")))))
Reads a NCName, taking into account that whitespaces and characters: ( ) < > [ ] : / + * , = | ! " ' @ $ may not be used in it. Moreover, its first character can't be: . - or a digit The result: (list ncname new-path) or #f ncname - NCName represented as a string If there is no NCName in the current position of the path, then an error message is displayed and #f is returned
(define (sxml:parse-ncname path) (let((path (sxml:skip-ws path))) (cond ((null? path) (sxml:xpointer-parse-error "unexpected end of XPointer path. Expected - NCName")) ((sxml:non-first? (car path)) (sxml:xpointer-parse-error "expected - NCName instead of " (car path))) (else (let loop ((ncname (list (car path))) (path (cdr path))) (cond ((null? path) (list (list->string (reverse ncname)) path)) ((memv (car path) sxml:delimiter) (list (list->string (reverse ncname)) path)) (else (loop (cons (car path) ncname) (cdr path)))))))))
Reads a Name production. It is similar to a 'parse-ncname' function. The only difference is that #\: is allowed within a Name
(define (sxml:parse-name path) (let ((path (sxml:skip-ws path))) (cond ((null? path) (sxml:xpointer-parse-error "unexpected end of XPointer path. Expected - Name")) ((and (sxml:non-first? (car path)) (not (char=? (car path) #\:))) (sxml:xpointer-parse-error "expected - Name instead of " (car path))) (else (let loop ((ncname (list (car path))) (path (cdr path))) (cond ((null? path) (list (list->string (reverse ncname)) path)) ((and (memv (car path) sxml:delimiter) (not (char=? (car path) #\:))) (list (list->string (reverse ncname)) path)) (else (loop (cons (car path) ncname) (cdr path)))))))))
The function reads a qualified name (QName) Returns: ( (prefix . local-part) new-path ) or ( local-part new-path ) if there is no prefix if there is not QName in the beginning of the 'path' it calls sxml:xpointer-parse-error prefix, local-part - strings new-path - a list of characters
(define (sxml:parse-qname path) (and-let* ((r1 (sxml:parse-ncname path))) (let ((first (car r1)) (path2 (cadr r1))) (cond ((null? path2) (list first path2)) ((not (char=? (car path2) #\:)) (list first path2)) ((null? (cdr path2)) (sxml:xpointer-parse-error "no local part of a qualified name")) ((char=? (cadr path2) #\:) (list first path2)) (else (and-let* ((r2 (sxml:parse-ncname (cdr path2)))) (list (cons first (car r2)) (cadr r2))) )))))
Reads a natural number: [1-9] [0-9]* The result: (list number new-path) or #f
(define (sxml:parse-natural path) (let ((path (sxml:skip-ws path))) (cond ((null? path) (sxml:xpointer-parse-error "unexpected end of XPointer path. Expected - number")) ((or (char<? (car path) #\1) (char>? (car path) #\9)) (sxml:xpointer-parse-error "expected - number instead of " (car path))) (else (let loop ((res (- (char->integer (car path)) 48)) ; (char->integer #\0) (path (cdr path))) (cond ((null? path) (list res path)) ((char-numeric? (car path)) (loop (+ (* res 10) (- (char->integer (car path)) 48)) ; (char->integer #\0) (cdr path))) (else (list res path))))))))
Reads a Literal ([29] in XPath specification) [29] Literal ::= '"' [^"]* '"' | "'" [^']* "'" The result: (string new-path) or #f
(define (sxml:parse-literal path) (let ((ch (if (sxml:parse-check "\"" path) #\" #\'))) (let loop ((res '()) (path (sxml:parse-assert (if (char=? ch #\") "\"" "'") path))) (cond ((not path) #f) ((null? path) (sxml:parse-assert (if (char=? ch #\") "\"" "'") path) #f) ((char=? (car path) ch) (list (list->string (reverse res)) (cdr path))) (else (loop (cons (car path) res) (cdr path)))))))
Reads a Number ([30]-[31] in XPath specification) [30] Number ::= Digits ('.' Digits?)? | '.' Digits [31] Digits ::= [0-9]+ The result: (number new-path) or #f
(define (sxml:parse-number path) (define (digits path) (let loop ((n-lst '()) (path path)) (cond ((and (null? path) (null? n-lst)) (sxml:xpointer-parse-error "unexpected end of XPointer path. Expected - number")) ((null? path) (list n-lst path)) ((and (or (char<? (car path) #\0) (char>? (car path) #\9)) (null? n-lst)) (sxml:xpointer-parse-error "expected - number instead of " (car path))) ((or (char<? (car path) #\0) (char>? (car path) #\9)) (list n-lst path)) (else (loop (cons (- (char->integer (car path)) (char->integer #\0)) n-lst) (cdr path)))))) (let ((path (sxml:skip-ws path))) (cond ((null? path) (sxml:xpointer-parse-error "unexpected end of XPointer path. Expected - number")) ((char=? (car path) #\.) (and-let* ((lst (digits (cdr path)))) (let rpt ((res 0) (n-lst (car lst)) (path (cadr lst))) (if(null? n-lst) (list (/ res 10) path) (rpt (+ (/ res 10) (car n-lst)) (cdr n-lst) path))))) (else (and-let* ((lst (digits path))) (let loop ((num1 0) (n-lst (reverse (car lst))) (path (cadr lst))) (if (null? n-lst) (cond ((null? path) (list num1 path)) ((not (char=? (car path) #\.)) (list num1 path)) (else (and-let* ((lst2 (digits (cdr path)))) (let rpt ((num2 0) (n-lst (car lst2)) (path (cadr lst2))) (if (null? n-lst) (list (+ num1 (/ num2 10)) path) (rpt (+ (/ num2 10) (car n-lst)) (cdr n-lst) path)))))) (loop (+ (* num1 10) (car n-lst)) (cdr n-lst) path))))))))


MCollective » Deploy » Install MCollective
Summary
Note: This page is about installing MCollective. Installation is only one step of a many-step deployment process. See the MCollective deployment index for the complete picture.
- Make sure your middleware is up and running and your firewalls are in order.
- Install the
mcollective
package on servers, then make sure themcollective
service is running. - Install the
mcollective-client
package on admin workstations. - Most Debian-like and Red Hat-like systems can use the official Puppet Labs packages. Enable the Puppet Labs repos, or import the packages into your own repos.
- If you’re on Debian/Ubuntu, mind the missing package dependency.
- If your systems can’t use the official packages, check the system requirements and either build your own or run from source.
Best Practices
Use site-wide configuration management software to install and configure MCollective. Since you’ll need to install the server daemon on every node in your deployment, and since you’ll want each node to be running the same version, you should generally use Puppet or something like it to install MCollective.
Version Notes
MCollective uses a three-part “x.y.z” version number.
- The first digit doesn’t have a particularly strict definition, but generally increments for major architectural breaks and incompatibilities.
- The second digit indicates whether this is a stable release: even numbers are stable and production-ready, and odd numbers are unstable development branches in which breaking changes may happen in minor point releases.
- The third digit reperesents the minor point release; in a stable version series, these should only contain bugfixes, and in an unstable series they may contain anything.
Pre-Install
- Your middleware system should be deployed before installing MCollective.
- Make sure each server’s firewall will allow MCollective to initiate connections with the middleware server. The port depends on your deployment plan; with the recommended ActiveMQ connector, this will usually be either 61614 for Stomp/TLS (recommended) or 61613 for unencrypted Stomp, depending on how you configured ActiveMQ’s transport connectors.
System Requirements
MCollective can run on almost any *nix operating system, as well as Microsoft Windows. It requires one of the following Ruby versions:
- 1.9.3
- 1.8.7
Ruby 2 is not officially supported yet, but may work fine. Ruby 1.8.5 can’t use TLS when connecting to the middleware, but works fine over unencrypted connections. Ruby 1.8.6 has the same problem as 1.8.5, and somewhat less automated test coverage. Ruby 1.9.0 through 1.9.2 are NOT supported, and are expected to fail.
MCollective also requires the Stomp rubygem, version 1.2.2 or higher. The instructions below will note when this has to be handled manually.
Official Packages
Puppet Labs provides official pre-built packages for the most common Linux-based operating systems. If you are running any of these systems, you can use the “Official Packages” install instructions.
Red Hat-Like
- Enterprise Linux 5 (including RHEL, CentOS, etc.) (also supported by Puppet Enterprise)
- Enterprise Linux 6 (also supported by Puppet Enterprise)
- Fedora 16
- Fedora 17
Debian-Like
- Debian 6 “Squeeze” (current stable release) (also supported by Puppet Enterprise)
- Debian “Wheezy” (current testing distribution)
- Debian “Sid” (current unstable distribution)
- Ubuntu 12.04 LTS “Precise Pangolin” (also supported by Puppet Enterprise)
- Ubuntu 10.04 LTS “Lucid Lynx” (also supported by Puppet Enterprise)
- Ubuntu 8.04 LTS “Hardy Heron”
- Ubuntu 12.10 “Quantal Quetzal”
- Ubuntu 11.10 “Oneiric Ocelot”
Puppet Enterprise
Puppet Enterprise includes MCollective, and automates the entire deployment process. See the PE orchestration documentation for more details; see the PE installation instructions to install PE.
Puppet Enterprise 2.8 ships with MCollective 1.2.1.
Installing With the Official Packages
Install Stomp Gem (Debian/Ubuntu)
The current MCollective packages for Debian and Ubuntu have a missing dependency on the Stomp gem (issue 17804). Before installing MCollective, you must install version 1.2.2 or higher of the Stomp rubygem. Use one of the following, making sure to check the version:
- The distro’s
libstomp-ruby
package (older releases) - The distro’s
ruby-stomp
package (newer releases) - The
stomp
gem
Enable Repos or Add Packages
To use the official packages, you must first either enable the Puppet Labs package repositories on all systems, or import the following packages from our repo into your local repo:
mcollective
mcollective-client
mcollective-common
rubygem-stomp
(on Enterprise Linux variants)
Install MCollective
- On server nodes, install the
mcollective
package. - On admin workstations, install the
mcollective-client
package.
Both of these packages install mcollective-common
as a dependency.
Enable the MCollective Service
Ensure that the mcollective
service is running and is enabled to start at boot. The mcollective
package installs an init script that works with your system’s normal service tools.
Done
At this point, MCollective is installed and running, but cannot connect to the middleware, accept commands, or execute any actions. You should now configure the server daemon, configure admin workstations, and deploy plugins. See the standard deployment getting started guide for details.
Example
As mentioned above and in the server config reference, you should use Puppet or some other configuration management software to deploy MCollective on your server nodes. This can be done with a simple or modified package/file/service pattern.
The example below uses a modified pattern. It assumes:
- You are managing settings as resources in a different class.
- You are maintaining your own package repository with pre-tested versions of the MCollective packages, allowing
ensure => latest
to be used safely. All servers were deployed with this local repository enabled. - You are managing client workstations separately, and only automating deployment on your server nodes.
class mcollective {
# Manage Stomp gem dependency on Debian/Ubuntu
package {'stomp':
ensure => '1.2.2',
provider => gem,
before => Package['mcollective'],
}
# Install
package {'mcollective':
ensure => latest,
}
# Run
service {'mcollective':
ensure => running,
enable => true,
require => Package['mcollective'],
}
# Restart the service when any settings change
# (see http://docs.puppetlabs.com/puppet/latest/reference/lang_collectors.html and
# http://docs.puppetlabs.com/puppet/latest/reference/lang_relationships.html#chaining-arrows
# for syntax details)
Package['mcollective'] -> Mcollective::Setting <| |> ~> Service['mcollective']
}
Rolling Custom RPM and Deb Packages
If you use an RPM-based or deb-based Linux distribution not supported by the official Puppet Labs packages, you can build your own packages with the same automated tooling Puppet Labs uses.
More detailed instructions on this are forthcoming; for the time being, obtain a copy of the source and do a quick read-through of the Rakefile. The relevant tasks are named deb
and rpm
.
Once you have packages, they will behave much like the official ones; follow the same instructions above.
Running From Source
On platforms not supported by the official packages or the underlying RPM and deb tooling, you can run MCollective directly from source.
Obtain Source
Get a copy of the MCollective source, either by cloning the GitHub repo or downloading a tarball.
Install Ruby and the Stomp Gem
Make sure Ruby is installed and that your system’s Ruby version meets MCollective’s system requirements.
Install version 1.2.2 or higher of the stomp
rubygem.
Add mcollective/lib
to Ruby’s Load Path
Ruby must be able to load the contents of the lib
directory in the MCollective source. There are two main ways to do this:
- Recursively copy the contents of
lib
into thesite_ruby
directory - Put the MCollective source somewhere like
/opt
and use theRUBYLIB
environment variable to add it to Ruby’s load path.
Put mcollective/plugins
Somewhere Sensible
MCollective ships with a set of plugins it requires for basic functionality; these do not live in its normal lib path, but in an external directory specified by the libdir
setting in MCollective’s server and client config files.
You should copy the contents of this plugins
directory to some platform-appropriate place; remember the location for your post-install configuration, since you need to specify it in the libdir
setting. Red Hat-like platforms put plugins in /usr/libexec/mcollective
. Debian-like platforms put it in /usr/share/mcollective/plugins
. Your platform may have its own conventions.
Note: MCollective expects its
libdir
to contain a single directory namedmcollective
, which then contains the rest of the plugin directories. Be sure to not accidentally put your plugins in the directory above the one MCollective will look in.Example:
# /etc/mcollective/server.cfg # ... libdir = /usr/libexec/mcollective
- Good:
/usr/libexec/mcollective/mcollective/agent/discovery.rb
- Bad:
/usr/libexec/mcollective/agent/discovery.rb
(This would only work if you had set alibdir
of/usr/libexec
.)
Add mcollective/bin
to the Path
The root user on each server node must be able to execute the mcollectived
binary. Admin users must be able to execute the mco
binary. You should either copy these to someplace like /usr/local/bin
and /usr/local/sbin
, or add the directory they live in to the appropriate users’ PATH
environment variable.
Roll Your Own Init Script
There are several example init scripts in the MCollective source:
There may be other helpful files for your platform in the mcollective/ext
directory. Use some combination of these to make a platform-appropriate init script for the MCollective server daemon.
Done
At this point, MCollective is installed and running, but cannot connect to the middleware, accept commands, or execute any actions. You should now configure the server daemon, configure admin workstations, and deploy plugins. See the standard deployment getting started guide for details.
Unlike with the official packages, you won’t be able to count on sensible defaults for the config files, so take special note of the logging settings and libdir
setting.
Installing on Windows
We currently have no instructions for installing MCollective on Windows. You should investigate the ext/windows
directory in the MCollective source. If you’ve used MCollective on Windows, we’d love to hear about your experience, especially any unexpected pitfalls you ran into. Email faq@puppetlabs.com.


My name is Renato M. Dinco III. I am college student in Adventist University of the Philippines. When I was a kid, I want to be a Police Man because my mother is Police Woman in my town and my mother always bring me in to her work. That is why I dream to be a Police Man. Now I am taking Bachelor of Science Information Technology but I will never give that dream. I want also to be a good programmer. I am 21 years old now. I am 2nd year college now. I want to help my family soon and give them a better life.
Computer skills involve the ability to learn and operate various technology. Hardware skills allow you to physically operate a computer, and can be as simple as knowing how to turn devices on and off. Software skills help you to efficiently use computer programs and applications.
Active listening is the ability to focus completely on a speaker, understand their messages, comprehend the information and respond thoughtfully. Active listeners use verbal and non-verbal techniques to show and keep their attention on the speaker. Developing and using active listening skills can show your colleagues that you engaged and have interest in the project or task at hand.
Time management skills allow you to complete tasks and projects before deadlines while also maintining work-life balance. Staying organized can help you allocate your work day to specific tasks by importance. Deeply undertanding your individual, team and company goals can provide a starting point when deciding how to manage your time.
PHP stands for Hypertext Preprocessor. It's an open source, server-side, scripting language used for the development of web applications. By scripting language, we mean a program that is script-based(lines of code) written for the automation of tasks.
JavaScript is a dynamic computer programming language. It is lightweight and most commonly used as a part of web pages, whose implementations allow clientside script to interact with the user and make dynamic pages. It is an interpreted programming language with object-oriented capabilities.
Phyton is a high-level programming language to be easy to read and simple to implement. It is open source, which means it is free to use, even for commercial applications. Phyton can run on Mac, Windows, and Unix systems and has also been ported to Java and .Net virtual machines.
Java is a high-level programming language developed by Sun Microsystems. It was originally designed of developing programs for set-top boxes and handled devices, but later became a popular choice for creating web Applications.


Connected determinant space is too big! \( \hat{V}\ket{\Psi_0} \sim O(N_{\mathcal{V}} N_e^2 N_{unocc}^2) \rightarrow 10^{12} \)
We can include only the "important" configurations like we did in the variational stage
We can calculate \( E_2(\epsilon_2) \) stochastically sampling the variational space i.e. \( \mathcal{V}_{stoc.} \subset \mathcal{V} \)
We can reduce the stochastic noise by calculating as much of \( E_2 \) deterministically as possible
$$ E_2 = E_2^D (\epsilon_2^D) + (E_2^S (\epsilon_2) - E_2^S (\epsilon_2^D)) $$


Catagorized bug lists
String interpolation error()
Bug - missing prefex in string interpolation
https://github.com/lift/framework/commit/dc632a927a22a9b81ff5422fdc1ba389ce47595f
Bug - broken string interpolation(missing prefix)
https://github.com/lift/framework/commit/51b4f9dbf672d12a3aa5227e4fbecdadf6493bf5 Regex : [\W]"[^"]\${[^"]}[^"]*"
Obvious error
Bug - self calling(an obvious error, with function self-calling without any change to parameters)
https://github.com/sksamuel/elastic4s/commit/ae73cd393cb967278aa92e53f6c480af0a7e2fac https://github.com/nicta/scoobi/commit/20c875e1a1fb2710e7efd8a1dd211e8b3cda1341 https://github.com/storm-enroute/reactive-collections/commit/0761e212e486e624dd2f3a69bdcbcb541deb64a9
Bug - function name conflict(addHeader() and setHeader())
https://github.com/skinny-framework/skinny-framework/commit/5c9362edb0905f20c06e94b9bde00ec94b21b042
[Bug]ambiguous name
https://github.com/milessabin/shapeless/commit/ddd46e7a6ce856904b5c52b55278f487f47eb634
Bug - some obvious function misuse
https://github.com/sksamuel/elastic4s/commit/3748069f982accf1ba94c4defd4aac16ba39fd1e
[Not Found] - "0000" means that something is missing
https://github.com/factorie/factorie/commit/10041d13117a88c364ae48caddb563477af850b1
[Not Found] - has/is should be something==null
https://github.com/storm-enroute/reactive-collections/commit/4032970311a636d78b4daa742e7d3f98fa7acaf4 - The following need to analyze source code, not compiled .class)
Bug - wrong intended null evaluation
https://github.com/lift/framework/commit/7cc7134c37a599dd7f80a646eb0ce49d1d318862 Regex : if.((.(!=|ne)\snull)|null\s(!=|ne).).Nil
Bug - damn typo...(class name is "not in", but toString() return "in")
https://github.com/fwbrasil/activate/commit/36dcc53026e665751a4de0ee3d1c760e3b1b200f check : Duplicate toString values in case class with only one string involved, and class names are different Regex : def toString\s=\s"[^"]*"
Bug - use before init(should be -> if(initialize) then do some work)
https://github.com/fwbrasil/activate/commit/02f7ec4a005642b01b348bdaee11cf39a922cbc4
Bug - check for unclosed bracket(If use IDE, obviously these errors can be eliminated)
https://github.com/skinny-framework/skinny-framework/commit/2134a1c5ccae5a83d9d2efd8eb33b34849fdcfd2 [Bug]same var used twice between statement https://github.com/twitter/algebird/commit/3dab7aa8ac8e093dfb367476c5672e844ff6a818 [Bug]increment inside condition, which leed to infinite loop(i++ in if statement) https://github.com/storm-enroute/reactive-collections/commit/a06257201def332e59f5966f37d21f47ef290f00 [Bug]False condition(could be detected by NullChecker in findBugs) https://github.com/storm-enroute/reactive-collections/commit/5d6581c23641141cfacb9491c5e8f1426383c39f
Concurrency and Lock
Bug - concurrent lock error(index in unload() is not protected by lock)
https://github.com/fwbrasil/activate/commit/2aa63ec3dc64db66decbcd274b8443422da1b4c5
Bug - read/write lock(Move lazy inside lock scope, but why?)
https://github.com/fwbrasil/activate/commit/70fbe4070a56ec336fad71a0579c0f9f78c92831
Bug - concurrent delete(not all map.put are protected, so duplicated get() will lead to different result)
https://github.com/fwbrasil/activate/commit/afc003b2c7d669008dacd20686dae5dbb86875a8
Bug - deadlock(one holds asyncSync while another holds msgCallbackSync)
https://github.com/lift/framework/commit/820a15d7a2c5e2bb4eb00352b325412393329998
Bug - reentrantreadwritelock deadlock(one holds readlock and another holds writelock, but why writelock could be held twice?)
https://github.com/lift/framework/commit/9dc635255f15bca027db5735e94ddfbbd800aa56
NPE
Bug - possible Null Pointer exception
https://github.com/fwbrasil/activate/commit/43ff0a11562ff1628cbbd618994ca22cdeeb0276
Bug - get empty element from map
https://github.com/fwbrasil/activate/commit/11d7c89632855104cc91be0b05cc40b0deed38b9
Bug - undefined field(in Reflection.getStatic())
https://github.com/fwbrasil/activate/commit/11d7c89632855104cc91be0b05cc40b0deed38b9
Bug - not-safe use of toString
https://github.com/skinny-framework/skinny-framework/commit/35c06c50515988cf49a6092a83fc640fd852f2d9
Bug - should check Null ahead
https://github.com/skinny-framework/skinny-framework/commit/56495db870122bda1c77f32e4f0b52b97677d80a
Bug - Check null
https://github.com/playframework/playframework/commit/f5971e788a4af7037e1df86b3151a7229df60018 https://github.com/playframework/playframework/commit/2bcf2c1a7a86f4d1b1db8306a1656f0db1a75d75 https://github.com/storm-enroute/reactive-collections/commit/6e66926bf2380a94d4c6be5b9e495b754ca311a6 https://github.com/aselab/scala-activerecord/commit/10d9069bf62f8217e04bdba3d20ed3f590fdce22
Bug - Another NPE(hard to detect)
https://github.com/skinny-framework/skinny-framework/commit/2e2a5b439a6a2a5fa1098ac33fe0fa701d782b77 https://github.com/lift/framework/commit/0836f2a926c33bf72d8babe36d958653b146bbc1 https://github.com/lift/framework/commit/ce4bf6f1a5d1c8c71001e24ca537c5800ac7c541 https://github.com/lift/framework/commit/a09b633327405cf3c4aad2c0c124ea5b897428b5
Bug - null check of string
https://github.com/lift/framework/commit/e6d70f393e32493bfc413ddad79711340903992a https://github.com/lift/framework/commit/5312678ef896a5a5de1063b4b54b391df77d1738 https://github.com/lift/framework/commit/edebbd744804ce7f4e3e15d2512e53d304ee5b78 https://github.com/lift/framework/commit/1e24fe928cdfd482445b8fa5223cad3dc956acf2
Bug - null serialization
https://github.com/lift/framework/commit/97b92da891458b447946bdc2b8678a26f831fc19 https://github.com/aselab/scala-activerecord/commit/e43f4ac6a1303cbf4905a914982da1b8f9e9ab56
[Bug] should check exist first
https://github.com/unfiltered/unfiltered/commit/2d3706f7e03ac923be7fc55d87ad0b2f06cfdf77
Pattern Matching
Bug - case fallthrough(In scala, case will not fall through, so any empty => block will be suspicious)
Regex : (high false-positive) \scase.=>\s* \s*(case|}) https://github.com/fwbrasil/activate/commit/3bac399611f04ee2792d03ec71b102f937452637
Bug - bad matching syntax, should be _(Invalid matching syntax)(Compile error)
https://github.com/mauricio/postgresql-async/commit/6e81e4adcb016cbd7b1e3ed36d5535d9cb6fa762
Bug - nonsense behavior of match(what does "()" do)
https://github.com/lift/framework/commit/aab84d819cc6f2abe040f6a84dd6949bb156256a
Pointer OutOfBound
[Bug]mat.length is < n, so mat(n-1) is out of bound
https://github.com/BIDData/BIDMach/commit/21942503ceca49eb6b862c7e1b74b51455d1523c
Pattern matching is not complete
Bug - missing default match option(this matching cannot generate "True" result for boolean matching)
https://github.com/lift/framework/commit/77ba2b73e800358405f9bbbe1e2ac3f26126d951
Bug - missing default match
https://github.com/lift/framework/commit/9b370d1bf627a38ebc0bdd7b8aa0152653f49807 https://github.com/lift/framework/commit/97c08c7dd9ed161a83f6c3b716e03bbec98f28fc
Bug - dead match condition(This one needs further check)
https://github.com/lift/framework/commit/deb27666c0f8936aa12763afd74aba1439305f40
All except this
Bug - if everyone use, everyone should use (file is used in matching case but not in processing block)
https://github.com/scalatra/scalatra/commit/5bc791191f78c6fecd3e6d5f68474c7c84593869
Bug - missing .value(all except one pattern)
https://github.com/eed3si9n/scalaxb/commit/c90cb88c760d67b804df2a2418b4e5a60661656c
Function return type(Need to study how type is generated)
Missing return type is not a bug
Bug - error with return type
https://github.com/skinny-framework/skinny-framework/commit/ed865e0cc193df6cdb8b478b7cb5c5a4d901612e
Bug - type mismatch
https://github.com/lift/framework/commit/1ffac230fea785e221e9ecb2a1b106c324700a2b [Bug] "return" in case and bad return type https://github.com/factorie/factorie/commit/1914891580b1e4cf7467b25fce2467f646d2193a [Bug]Return type error https://github.com/xitrum-framework/sclasner/commit/3ec95406d77b56f31a111192aeed76cd74059823
Type checking
Bug - check for type[Nothing]
https://github.com/adamw/macwire/commit/366611f2364678efd625a446a93341deb62b825c
Bug - argument type error(need further insight)(Cross check with function call)
https://github.com/lift/framework/commit/f01b9d5fc50533f3c2ba932357fac8c39a1fd1ea
Bug - incorrect type check
https://github.com/lift/framework/commit/ea5f68c2208ea3d7907e7a089b0883d89e54a876
Bug - type mismatch in pattern matching
https://github.com/lift/framework/commit/1c7c0c3c23e77c6c2adfb3eb36080cbed57530a8
Bug - missing parenthesis of omComplete in fromCallback1, with type: Unit => ()(http://stackoverflow.com/questions/6643030/what-is-the-rule-for-parenthesis-in-scala-method-invocation)
https://github.com/playframework/playframework/commit/6ec8f31fc9c632ab3d1eab29f441e5e8e3db4271
Enumeration
Bug - enum with duplicated value(value(10) was used twice)
https://github.com/lift/framework/commit/5f09c86fdc72ae163d2fc4d4415b764e3d92be1f
Syntax error or unsafe usage
[False] - incorrect usage of array buffer(obvious)
https://github.com/lift/framework/commit/0b80e60948498400639949422d6040744cc45c76
[Possible] - unsafe use of setObject() in optionToStatement
https://github.com/playframework/playframework/commit/08c3ee4d0430653caa4c167e9d5a0d3dc6cb529c
[Bug]Possible string out of bound error
https://github.com/jrudolph/sbt-dependency-graph/commit/0bcd2e03f49f6c7133e9ef9e40b95d40970e4a29
[Bug]reuse an iterator
https://github.com/twitter/algebird/commit/f8cbd5d52eabfcbbc99fa3ccb2af9cb1a5485959
[Bug] misuse of Array(missing new)
https://github.com/BIDData/BIDMach/commit/479faa4a9afa3d126019547809a8e140b545b65c
[Bug]False type compare syntax
http://docs.scala-lang.org/overviews/reflection/symbols-trees-types.html, ( == incorrectly reports that ) Regex : ==\s*typeOf[[^]]+]
Type misuse
[Bug][Case] int divided by int(density, which is used above, should be double instead of int)
https://github.com/twitter/algebird/commit/0642b720f71f15fe9180598b920b32d4ccc55e9d
[Bug] should use while to iterate through a HashMap(var table: Array[ReactMap.Entry[K, V]] = null)
https://github.com/storm-enroute/reactive-collections/commit/75797ed43c501bd0308a5c6ee7fa423f6c1f58ba
[False] false type(missing bracket)
https://github.com/factorie/factorie/commit/a1334905a4d5580ea82fbe8bca58ba5d5c2654a6
[Warning]use of not thread-safe type in val
https://github.com/maxcellent/lamma/commit/61c787957da76cf4dbfb5ce3f133b351dc8799cd
[Bug]False parameter type
https://github.com/xitrum-framework/glokka/commit/ef079563a97a24966c44e5e58dc8c82664921ff1
Unused function parameter
[Bug][Case] the var "req" in "handlerForRequest" is not used, instead, mispelled into "request" in function definition https://github.com/jroper/playframework/commit/7d22bf13830c7b072d22aaaee10fe7c5c4c8cc0c [Bug][Case] parameter "regex" should be used https://github.com/playframework/playframework/commit/8589377861f242be38bb5a85c2c472cade95f332 [Bug]unused function parameter https://github.com/etorreborre/specs2/commit/a455c55b6d0c014e36f18ec39260ec79a65afa4d
Override hashCode and equals
Regex : ^(?!override)\s*def hashCode() [Style] override members of the super class https://github.com/BIDData/BIDMach/commit/d35f06bc3ae4da8ab604635453ba512ef6d1477b


As an open source project and community,
we need your feedback
to make the next generation browser.
Meet some of the team that has been hard at work
on the Firefox 4 project.
I work on Web Standards like HTML 5, File APIs and IndexedDB.
We’re going to make the best and most secure browser out there!
We work on testing Firefox 4 beta.
We’d like to know what you think, we’d like your feedback.
You’re going to notice a feedback button
on the upper-right corner of your browser…
…that you can use to tell us
what you like and don’t like about Firefox 4.
Let me know what you think.
Im working on the Firefox 4 beta program.
I work on content security policy for Firefox 4.
We work on crash bugs.
I’m David and I work on developer tools for Firefox 4,
and I’d really like to know what you think.
We need as much feedback as possible.
I work on the Firefox 4 Sync servers.
Firefox Sync lets you take your Firefox experience with you
wherever you go.
And we’re really looking forward to your feedback.
I work on JetPack, which is a project
to make it easier to build Add-Ons and to make Add-Ons easier to use.
I worked on the new Add-ons manager in Firefox 4.
We’d really like to know your feedback
about what you love and hate about Firefox 4, so let us know.
Please help us and make Firefox better!