Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[REBOL] REBOL - Formal Specification - Help Wanted!

From: robbo1mark::aol::com at: 26-Feb-2001 11:35

REBOL - Formal Specification - Help Wanted! Everybody, This message is an open invitation | request | plea for HELP in writing a Formal Specification for REBOL in either Backus Naur Form (BNF) or Extended BNF notation, would also like advice on whether BNF or EBNF is better / more appropriate for this task. I have needed / meant to progress work on this for some time now, it is very important and a Formal Specification of REBOL is useful not only to the OSCAR Project but also to Java-REBOL & anybody else needing a more concise understanding of REBOL, whether for the purposes of building a REBOL "parser" or whatever. Iam currently designing a REBOL parser to be written in ANSI C for That Other Project and WILL need a Formal Specification for that purpose, however I thought it might speed things up if other people were willing to lend a hand, as they might need a Formal Spec. too for their own needs & purposes. I have enclosed below Garold L. Johnson's excellent REBOL script which is an excellent starting point for beginning writing a formal specification. If this is of serious interest to you please reply to this thread. Any help offered is gratefully welcomed as Iam a bit "snowed in" both figuratively and literally at the moment. ( For your info we got over 6 inches of snow here in Scotland last night. ) cheers everybody. Mark Dickson Rebol [ Name: 'Oscar Title: "Oscar" File: %Oscar_parse_03.r Author: ["Andrew Martin" "Garold L. Johnson" ] eMail: [Al--Bri--xtra--co--nz] Site: http://members.nbci.com/AndrewMartin/ Date: 11/November/2000 History: [ ver [date comment who] 0.1.7 [2000-Nov-28 {Removed special treatment of math chars in Word} glj] 0.1.6 [2000-Nov-27 {Removed all but '/' and '//' from MathOps} glj] 0.1.5 [2000-Nov-27 {Fix errors found in REBOL scripts} glj] 0.1.4 [2000-Nov-23 {Use same names as ascii.r} glj] 0.1.3 [2000-Nov-12 {Fix word / math problem} glj] 0.1.2 [2000-Nov-12 {Coding standards. All tokens attempted.} glj] 0.1.1 [2000-Nov-10 {Initial code} glj] 0.1.0 [2000-Nov-10 {Initial code} "Andrew Martin"] ] Comment: { This is evolutionary and experimental both on parsing and the actual grammar that it understands. There are problems separating certain math operators from words. It really needs a lookahead. e.g. +x -- word, + math op Handled by requiring allowing single math op characters to be math ops and requiring other words starting with math ops to be multi character. } ToDo: { Implement pair! datatype (int x int) -- Done. File! allows %"c/program files/rebol view/rebol.exe" construct. -- Done. } ] Oscar: make object! [ ; Character sets Upper: charset [#"A" - #"Z"] Lower: charset [#"a" - #"z"] Alpha: union Upper Lower Digit: charset [#"0" - #"9"] Alphanumeric: union Alpha Digit Hexadecimal: charset [#"0" - #"9" #"a" - #"f" #"A" - #"F"] Space: charset [#" " #"^/" #"^-"] ; Delim: charset "[](){}^":;" ; Delim: union Delim Space Tick: #"'" Colon: #":" Semicolon: #";" Quote: #"^"" Period: #"." Pound: #"#" ; Override ascii.r. Use all characters including high bit to allow parsing this file! Printable: charset [ #"^(20)" - #"^(ff)" ] ; Word_Extra: charset "?!.&_~`" ; Math_Word: charset "+-*|=" ; glj -- merge with Word_Extra Word_Extra: charset "?!.&_~`+-*|=" ; Word_Start: union Alpha union Word_Extra Math_Word ; Word_Body: union Alphanumeric union Word_Extra union Math_Word charset Tick Word_Start: union Alpha Word_Extra Word_Body: union Alphanumeric union Word_Extra charset to-string Tick Extra-URL: charset "-_." URL_Extra: charset "-_." URL_Body: union Alphanumeric URL_Extra Dec_Point: charset ".," ; Recognizer rules oComment: [Semicolon to newline ] ; Must be multiple chars if starts with math symbol -- glj ; Word_1: [ Math_Word some Word_Body ] -- pointless -- glj ; Word_2: [ Word_Start any Word_Body ] ; oWord: [ Word_1 | Word_2 ] Cmp_Op: [ "<>" | "<=" | "<" | ">=" | ">" ] ; oMath_Op: [ "+" | "-" | "*" | "//" | "/" | "|" ] Math_Op: [ "//" | "/" ] Word_1: [ Word_Start any Word_Body ] oWord: [ Word_1 | Cmp_Op | Math_Op ] oSet_Word: [oWord Colon] oGet_Word: [Colon oWord] oLit_Word: [Tick oWord] ; Strings are enclosed in braces or quotes. ; Brace strings allow properly nested braces. ; Strings support character escapes. Mixed_Match: function [ "Creates mixed case parse rule" Str [string!] "String to match" ] [ result c cs ] [ result: copy [] foreach c Str [ cs: to-string c append/only result reduce[ copy Uppercase cs '| copy Lowercase cs ] ] result ] ; Literals for character escapes Esc_Line: Mixed_Match "LINE" Esc_Tab: Mixed_Match "TAB" Esc_Page: Mixed_Match "PAGE" Esc_Back: Mixed_Match "BACK" Esc_Null: Mixed_Match "NULL" Esc_Escape: Mixed_Match "ESCAPE" Esc_Esc: Mixed_Match "ESC" Esc_Del: Mixed_Match "DEL" Char_Esc: [ "^^" [ Alpha | "^^" | {"} | "{" | "}" | "/" | "-" | "~" | "[" | "\" | "]" | "_" | "@" | [ "(" [ Esc_Line | Esc_Tab | Esc_Page | Esc_Back | Esc_Null | Esc_Escape | Esc_Esc | Esc_Del | [ 2 Hexadecimal ] ] ")" ] ] ; caret ] Quote_Str_Except: charset "^^^"" Quote_Str_Char: union Printable charset "^-^/" Quote_Str_Char: difference Quote_Str_Char Quote_Str_Except Quote_Str: [ #"^"" any [ Quote_Str_Char | Char_Esc ] #"^"" ] Brace_Str_Except: charset "{}^^" Brace_Str_Char: union Printable charset "^-^/" Brace_Str_Char: difference Brace_Str_Char Brace_Str_Except Brace_Str: [ #"{" (brace_nest: brace_nest + 1) [ any [ Brace_Str_Char | Char_Esc | Brace_Str ] ] #"}" ( brace_nest: brace_nest - 1 if brace_nest < 0 [ print [ "Illegal brace nesting in string!" ] exit ] ) ] oString: [ (brace_nest: 0) [ Quote_Str | Brace_Str ] ( if brace_nest <> 0 [ print [ "Illegal brace nesting in string (" brace_nest ")!" ] ] token_type: 'string ) ] ; # types Char_Quote: difference Printable Quote_Str_Except oChar: [ Pound Quote [ Char_Esc | Char_Quote ] Quote ] oIssue: [ Pound any Alphanumeric any [ "-" some Alphanumeric ]] oBinary: [0 2 Digit "#{" any [Alphanumeric | Space | newline] "}"] ; Numbers Sign: charset "+-" Dec_Point: charset ".," Int: [ Digit any [ Digit | Tick ] ] Num: [ some Digit ] Exp: [ [ #"E" | #"e" ] opt Sign Int ] Frac: [ Dec_Point Int opt Exp ] Whole: [ Int Dec_Point opt Int opt Exp ] oDecimal: [ opt Sign [ Whole | Frac ] ] oPair: [ opt Sign Num [ "x" | "X" ] opt Sign Num ] oInteger: [ opt Sign Int ] Currency: [ "$" ] ; Dollars oMoney: [ 0 3 Alpha Currency [oDecimal] ] oTuple: [ Num Period Num Period opt [Num 0 8 [Period Num]] ] ; Positive decimal Pos_Frac: [ Dec_Point Num ] Pos_Whole: [ Num Dec_Point any Digit ] Pos_Decimal: [ Pos_Frac | Pos_Whole ] ; AM_PM: ["A" | "a" | "P" | "p"] ["M" | "m"] ] AM_PM: reduce [ Mixed_Match "AM" '| Mixed_Match "PM" ] Time_1: [ 1 2 Digit Colon [Pos_Decimal | [1 2 Digit opt AM_PM]] ] Time_2: [ 1 2 Digit Colon 1 2 Digit Colon [Pos_Decimal | [1 2 Digit opt AM_PM]] ] oTime: [ Time_2 | Time_1 ] ; Dates Year: [ [4 digit] | [2 digit] ] Month: [ [1 2 Digit] | [1 12 Alpha] ] Date_1: [ 1 2 Digit "/" Month "/" Year ] Date_2: [ 1 2 Digit "-" Month "-" Year ] Date_3: [ [4 Digit] "/" Month "/" 1 2 Digit ] Date_4: [ [4 Digit] "-" Month "-" 1 2 Digit ] Date_5: [ Date_3 | Date_4 | Date_1 | Date_2 ] oDate: [ Date_5 opt [ "/" oTime opt [ Sign 0 2 Digit Colon 0 2 Digit ] ] ] Hex_Encode: [ "%" 2 Hexadecimal ] URL_Extra: charset "-_." URL_Body: union Alphanumeric URL_Extra oUrl: [ some Alpha "://" opt [ some Alphanumeric colon some Alphanumeric "@" ] any [URL_Body | Hex_Encode] ; glj -- some -> any any [ "/" any [URL_Body | Hex_Encode] ] opt [ Colon any Digit ] ; ports ] oEmail: [ Alpha any URL_Body "@" Alpha any URL_Body ] File_1: [ {%"} some [URL_Body | Hex_Encode | "/" | " "] {"} ] File_2: [ {%} some [URL_Body | Hex_Encode | "/"] ] oFile: [ File_1 | File_2 ] oTag: [ "<" [ Alpha | "/" ] thru ">" ] oBlock: [ "[" | "]" | "(" | ")" ] oValues: [ [ ; Always remember to put the longer or more specific rules first! ["#!" thru newline] ; Script path line | copy oComment! oComment (print ["Comment:" oComment!]) | copy oChar! oChar (print ["Char:" oChar!]) | copy oIssue! oIssue (print ["Issue:" oIssue!]) | copy oBinary! oBinary (print ["Binary:" oBinary!]) | copy oString! oString (print ["String:" oString!]) | copy oMoney! oMoney (print ["Money:" oMoney!]) | copy oTuple! oTuple (print ["Tuple:" oTuple!]) | copy oDecimal! oDecimal (print ["Decimal:" oDecimal!]) | copy oTime! oTime (print ["Time:" oTime!]) | copy oDate! oDate (print ["Date:" oDate!]) | copy oPair! oPair (print ["Pair:" oPair!]) | copy oInteger! oInteger (print ["Integer:" oInteger!]) | copy oEmail! oEmail (print ["Email:" oEmail!]) | copy oUrl! oUrl (print ["Url:" oUrl!]) | copy oFile! oFile (print ["File:" oFile!]) | copy oTag! oTag (print ["Tag:" oTag!]) | copy oSet_Word! oSet_Word (print ["Set_Word:" oSet_Word!]) | copy oGet_Word! oGet_Word (print ["Get_Word:" oGet_Word!]) | copy oLit_Word! oLit_Word (print ["Lit_Word:" oLit_Word!]) | copy oWord! oWord (print ["Word:" oWord!]) ; | copy oMath_Op! oMath_Op (print ["Math_Op:" oMath_Op!]) ; | copy oCmp_Op! oCmp_Op (print ["Cmp_Op:" oCmp_Op!]) | copy oBlock! oBlock (print ["Block:" oBlock!]) ] any space ] Parse: func [String [string!]] [ append String "^/" ; fix missing newline system/words/parse/all/case String [ any Space any oValues end ] ] ] O_1: does [ txt: read %glj_parse_test.r ; txt: read %oscar_parse_02.r print Oscar/parse trim txt comment { ; I'm a comment. Oscar: :Rebol 'Literallythis {I'm a long string.} "I'm a string" 1234567890 12.34 123.456 $987654321.23 NZL$9999.12 [Al--Bri--xtra--co--nz] http://www.dynalt.com/file name.txt http://members.nbci.com/AndrewMartin/Rebol/ 1.2.3.4.5.6.7.8.9.10 11:57 1:2 11/November/2000 <HTML> </HTML> 1 + 2 - 3 * 4 / 5 // 6 1 < 2 1 <= 2 1 = 2 1 >= 2 1 > 2 1 <> 2 } ] ; Main loop O_2: does [ echo %Oscar_Parse_trace.txt r_file: %/f/rebol/oscar/Oscar_Parse_results.txt f_file: %/f/rebol/oscar/Oscar_Parse_fail.txt write r_file "" write f_file "" files: sort read %/f/rebol/. foreach file files [ q: find file ".r" if q = %.r [ print to-string file text: read join %/f/rebol/ file print ["^/========== " file ] result: Oscar/parse text answer: rejoin ["File: " file "; Result = " result newline] print answer write/append r_file answer if not result [ write/append f_file answer ] ] ] ] ;halt