Add the RFC 5424 ABNF grammar for syslog messages, and fix char.char.char parsing.

This commit is contained in:
Dimitri Fontaine 2013-09-08 21:14:14 +02:00
parent 815e4fded0
commit 9025c58c4f

View File

@ -68,6 +68,63 @@
DIGIT = \"0\" / NONZERO-DIGIT" DIGIT = \"0\" / NONZERO-DIGIT"
"See http://tools.ietf.org/html/draft-ietf-syslog-protocol-15#page-10") "See http://tools.ietf.org/html/draft-ietf-syslog-protocol-15#page-10")
(defconstant +abnf-rfc5424-syslog-protocol+
" SYSLOG-MSG = HEADER SP STRUCTURED-DATA [SP MSG]
HEADER = PRI VERSION SP TIMESTAMP SP HOSTNAME
SP APP-NAME SP PROCID SP MSGID
PRI = \"<\" PRIVAL \">\"
PRIVAL = 1*3DIGIT ; range 0 .. 191
VERSION = NONZERO-DIGIT 0*2DIGIT
HOSTNAME = NILVALUE / 1*255PRINTUSASCII
APP-NAME = NILVALUE / 1*48PRINTUSASCII
PROCID = NILVALUE / 1*128PRINTUSASCII
MSGID = NILVALUE / 1*32PRINTUSASCII
TIMESTAMP = NILVALUE / FULL-DATE \"T\" FULL-TIME
FULL-DATE = DATE-FULLYEAR \"-\" DATE-MONTH \"-\" DATE-MDAY
DATE-FULLYEAR = 4DIGIT
DATE-MONTH = 2DIGIT ; 01-12
DATE-MDAY = 2DIGIT ; 01-28, 01-29, 01-30, 01-31 based on
; month/year
FULL-TIME = PARTIAL-TIME TIME-OFFSET
PARTIAL-TIME = TIME-HOUR \":\" TIME-MINUTE \":\" TIME-SECOND
[TIME-SECFRAC]
TIME-HOUR = 2DIGIT ; 00-23
TIME-MINUTE = 2DIGIT ; 00-59
TIME-SECOND = 2DIGIT ; 00-59
TIME-SECFRAC = \".\" 1*6DIGIT
TIME-OFFSET = \"Z\" / TIME-NUMOFFSET
TIME-NUMOFFSET = (\"+\" / \"-\") TIME-HOUR \":\" TIME-MINUTE
STRUCTURED-DATA = NILVALUE / 1*SD-ELEMENT
SD-ELEMENT = \"[\" SD-ID *(SP SD-PARAM) \"]\"
SD-PARAM = PARAM-NAME \"=\" %d34 PARAM-VALUE %d34
SD-ID = SD-NAME
PARAM-NAME = SD-NAME
PARAM-VALUE = UTF-8-STRING ; characters '\"', '\' and
; ']' MUST be escaped.
SD-NAME = 1*32PRINTUSASCII
; except '=', SP, ']', %d34 (\")
MSG = MSG-ANY / MSG-UTF8
MSG-ANY = *OCTET ; not starting with BOM
MSG-UTF8 = BOM UTF-8-STRING
BOM = %xEF.BB.BF
UTF-8-STRING = *OCTET ; UTF-8 string as specified
; in RFC 3629
OCTET = %d00-255
SP = %d32
PRINTUSASCII = %d33-126
NONZERO-DIGIT = %d49-57
DIGIT = %d48 / NONZERO-DIGIT
NILVALUE = \"-\""
"See http://tools.ietf.org/html/rfc5424#section-6")
#| #|
This table comes from http://tools.ietf.org/html/rfc2234#page-11 and 12. This table comes from http://tools.ietf.org/html/rfc2234#page-11 and 12.
@ -152,34 +209,42 @@ This table comes from http://tools.ietf.org/html/rfc2234#page-11 and 12.
(declare (ignore open close)) (declare (ignore open close))
(text val)))) (text val))))
(defrule range-sep (or "-" ".") (:constant :range-sep)) (defrule dec-string (and digits (+ (and "." digits)))
(:lambda (string)
(destructuring-bind (first rest) string
`(:sequence ,first ,@(mapcar #'cadr rest)))))
(defrule dec-range (and digits range-sep digits) (defrule dec-range (and digits "-" digits)
(:lambda (range) (:lambda (range)
(destructuring-bind (min sep max) range (destructuring-bind (min sep max) range
(declare (ignore sep)) (declare (ignore sep))
`(:char-class (:range ,min ,max))))) `(:char-class (:range ,min ,max)))))
(defrule dec-val (and "d" (or dec-range digits)) (defrule dec-val (and "d" (or dec-string dec-range digits))
(:lambda (dv) (:lambda (dv)
(destructuring-bind (d val) dv (destructuring-bind (d val) dv
(declare (ignore d)) (declare (ignore d))
val))) val)))
(defun hexadecimal-char-p (character) (defun hexadecimal-char-p (character)
(member character #. (quote (coerce "0123456789abcdef" 'list)))) (member character #. (quote (coerce "0123456789abcdefABCDEF" 'list))))
(defrule hexdigits (+ (hexadecimal-char-p character)) (defrule hexdigits (+ (hexadecimal-char-p character))
(:lambda (hx) (:lambda (hx)
(code-char (parse-integer (text hx) :radix 16)))) (code-char (parse-integer (text hx) :radix 16))))
(defrule hex-string (and hexdigits (+ (and "." hexdigits)))
(:lambda (string)
(destructuring-bind (first rest) string
`(:sequence ,first ,@(mapcar #'cadr rest)))))
(defrule hex-range (and hexdigits range-sep hexdigits) (defrule hex-range (and hexdigits range-sep hexdigits)
(:lambda (range) (:lambda (range)
(destructuring-bind (min sep max) range (destructuring-bind (min sep max) range
(declare (ignore sep)) (declare (ignore sep))
`(:char-class (:range ,min ,max))))) `(:char-class (:range ,min ,max)))))
(defrule hex-val (and "x" (or hex-range hexdigits)) (defrule hex-val (and "x" (or hex-string hex-range hexdigits))
(:lambda (dv) (:lambda (dv)
(destructuring-bind (d val) dv (destructuring-bind (d val) dv
(declare (ignore d)) (declare (ignore d))