(* NOTES: ? ign ? means that it will not be present in the syntax tree ? escape(chars) ? means that the named chars will be deescaped during scanning ? re(regex) ? means that this element must match the given regex in addition to its structural requirements (can be inverted) ? contains(regex) ? means that the element must contain somewhere within it the given regex (can be inverted) ? char ? matches any character terminal in the name of an identifier means that it will be represented directly in the syntax tree Terminal strings will be called "symbol" by the tokenizer Note for parser: parse 'val'-strings as node val; parse other-channel strings as 'atext'; parse FSM matched-strings as fsmstr *) (* val = { atext ? escape('{') ? | noderef } ; atext = { terminal string ? escape('<') ? | argref } ; noderef = lb , nname , [ nargs ] , [ ( colon , flist ) | ( exclam , ilist ) ] , rb ; nname = terminal string ? escape('{<') ? | atext ; nargs = atext ? escape('|') ? , { pipe , atext ? escape('|') ? } ; argref = lab , ( aref | function ) , rab ; function = terminal string ? re('[^<>()]*') ? , lp , [ aarg { pipe , aarg } ] , rp ; aarg = ( hash , aref ) | terminal int | terminal double | function | terminal string ? escape('|') ? ; aref = terminal int | elipsis | terminal string ; flist = [ fsep ? ign ? ] , { terminal double , fsep ? ign ? } | atext ; ilist = [ isep ? ign ? ] , { iref , isep ? ign ? } | atext ; iref = terminal int , [ colon , terminal double ] ; elipsis = [ ibound ] , '...' ? ign ? , [ ibound ] ; ibound = nil | atext - ( atext ? lazy ? , '...', atext ) ; fsep = terminal string ? re('[^0-9.]*[^0-9.+*=]') ? ; isep = terminal string ? re('[^0-9.:]*[^0-9.:]') ? ; fsmstr = { fsmaref | terminal string ? escape('{') ? } ; fsmaref = lb , terminal string ? escape('{') ? , rb ; *) (* template (inner) language (indirectly right-recursive) *) template-string = { terminal string ? escape('<', '\\') ? | ( lab , ( elipsis | function | aref ) , rab ) } ; function = terminal string ? re('[^<>()]*') ? , lp , [ arg { pipe , arg } ] , rp ; arg = elipsis | numeric-arg | terminal string ? escape('|)', '\\') ? ; numeric-arg ? macro ? = ( hash , aref ) | terminal int | terminal double | function ; aref = terminal int | terminal string ; elipsis = ibound , '...' ? ign ? , ibound ; ibound = nil | numeric-arg ; nil = '' ? ign ? ; lab ? ign ? = '<' ; rab ? ign ? = '>' ; lp ? ign ? = '(' ; rp ? ign ? = ')' ; hash ? ign ? = '#' ; (* replacement (outer) language (a regular language) *) val-string = { terminal string ? escape('{', '\\') ? | noderef } ; fsm-string = { terminal string ? escape('{', '\\') ? | fsmaref } ; oc-string = terminal string ; oc-string ? ch=freq ? = terminal double ; fsmaref = lb , terminal string ? escape('{}', '\\') ? , rb ; noderef = lb , nname , [ nargs ] , [ ( colon , flist ) | ( exclam , ilist ) ] , rb ; nname = terminal string ? escape('{}|:!', '\\') ? ; nargs = terminal string ? escape('|:!', '\\') ? , { pipe , terminal string ? escape('|', '\\') ? } ; flist = [ f-pre ] , { terminal double , fsep } ; f-pre = [ fsep ] , [ '+' | '*' | '=' ] , [ fsep ] ; ilist = [ isep ] , { iref , isep } ; iref = terminal int , [ colon , terminal double ] ; fsep ? ign ? = terminal string ? re('[^0-9.]*[^0-9.+*=]') ? ; isep ? ign ? = terminal string ? re('[^0-9.:]*[^0-9.:]') ? ; lb ? ign ? = '{' ; rb ? ign ? = '}' ; colon ? ign ? = ':' ; exclam ? ign ? = '!' ; (* Common symbols *) pipe ? ign ? = '|' ; terminal int = digit , { digit } ; terminal double = [ '-' ] ( digit , { digit } , '.' , { digit } ) | ( '.' , digit , { digit } ) ; terminal string = { ? char ? } ; (* template (inner) language (middle-recursive) adapted for YAEP *) TERM OTHERCHAR ; tstring : tstring string_nolab | tstring code | string_nolab | code ; string_nolab : string_nolab nolabCHAR # string (0 1) | nolabCHAR # string (0) ; nolabCHAR : DIGIT | ALPHA | '>' | '(' | ')' | '|' | '\\' '<' | PUNCT | OTHERCHAR ; code : '<' aref '>' # 2 | '<' function '>' # 2 | '<' elipsis '>' # 2 ; function : fname '(' [args] ')' # function (0 2) ; fname : fname fCHAR | fCHAR ; fCHAR : DIGIT | ALPHA | PUNCT ; args : args '|' arg # args (0 2) | arg ; arg : elipsis # arg 1 (0) | num_arg # arg 2 (0) | double # arg 2 (0) | string_nopipe # arg 3 (0) ; string_nopipe : string_nopipe '\\' '|' # string (0 2) | string_nopipe '|' error | string_nolab CHAR # string 2 (0 1) ; num_arg : '#' aref # 1 | int # 0 | function # 0 ; aref : int # int 1 (0) | string_alpha ; string_alpha : string_alpha ALPHA # string (0 1) | ALPHA # string (0) ; elipsis : [num_arg] '.' '.' '.' [num_arg] # elipsis(0 4) ; int : int DIGIT | DIGIT ; double : ['-'] int '.' [int] | ['-'] '.' int | ['-'] int ; CHAR : DIGIT | ALPHA | rPUNCT | PUNCT | OTHERCHAR (* from tokenizer. cntrl + all non-ASCII *) ; ALPHA : 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' ; DIGIT : '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' ; rPUNCT : '<' | '>' | '(' | ')' | '|' ; PUNCT : '\t' | '\n' | ' ' | '!' | '"' | '#' | '$' | '%' | '&' | '\'' | '*' | '+' | ',' | '-' | '.' | ':' | ';' | '=' | '?' | '@' | '/' | '[' | '\\' | ']' | '^' | '_' | '`' | '{' | '}' | '~' ;