parsing_combinators.txt revision 608:7e06bf1dcb09
1Parsing 2 3- primtive types 4- lists of various sorts 5 6 Basic models 7 8 prefix A,BCDF scans left-to-right 9 suffix ABCD:F scans right-to-left 10 11 Model 1: 12 data is sep,op,next,combine 13 14 if (sep found in data) 15 split data into prefix, rest 16 return combine( op(prefix), next(rest) ) 17 else 18 return combine( default, next(data) ) 19 20 pop = suffix1( ":", op3, op4, ++ ) 21 op = prefix1( ",", op2, pop, ++ ) 22 23 op( A,BDF.FGH:Z ) = 24 25 op2(A) ++ pop( BDF.FGH:Z ) = 26 op2(A) ++ op4( BDF.FGH ) ++ op3( Z ) 27 28 Model 2: 29 data is sep,op,next,combine 30 31 if (sep found in data) 32 split data into prefix, rest 33 return combine( op(prefix), next(rest) ) 34 else 35 return op(data) 36 37 example 38 op = prefix2( ":", op2, null, ++ ) 39 op.setNext( op ) ; 40 41 op( A:B:C:D ) = 42 43 op2(A) ++ op2(B) ++ op2(C) ++ op2(D) 44 45 46 47reduce( sep, initial, op, combine ) 48 49 operate( data ) 50 if (sep in data) 51 split data into prefix, rest 52 return combine( op(prefix), operate( rest )) 53 else 54 return combine( op(data), initial ) 55 56reduce( sep, op1, op2, initial, combine ) 57 58 operate(data) 59 if (sep in data) // either first from left orfirst from right 60 split data into prefix, rest 61 return combine( op1( prefix ), op2( rest ) ) 62 else 63 return opx( data ) 64 65type<X,Y> 66 class combine 67 init : X 68 add( X, Y ) : X 69 op1( String ) : X 70 op2( String ) : Y 71 72 reduce( sep, op1, op2, comb ) ( String ) : X 73 74 operate(data) 75 if (sep in data) // either first from left orfirst from right 76 split data into prefix, rest 77 return comb.add( op2.operate( rest ), op1.operate( prefix ) ) 78 else 79 return comb.add( comb.init(), op1.operate( data ) ) 80 81 example 82 83 op = reduce( ":", op1, null, comb ) 84 op.setop2( op ) 85 86 op.operate( "A:B:C" ) = 87 comb.add( op.operate( "B:C" ), op1.operate( "A" ) ) = 88 comb.add( comb.add( op.operate("C"), op1.operate("B") ), op1.operate( "A" ) = 89 comb.add( comb.add( comb.add( comb.init(), op1.operate("C") ), op1.operate("B") ), 90 op1.operate("A") ) 91 92 93Splitter interface 94 95interface Splitter { 96 List split( String str ) 97} 98 99variations: 100 - separated list SL 101 - first sep rest FSR 102 - fail if not present one arg 103 - default value two args 104 - rest sep last RSL 105 - fail if not present one arg 106 - default value two args 107 108Have we just pushed the real problem off a level? 109 110How do we combine: 111 op1 = FSR("@",v12) 112 op2 = LSR(":",9090) 113 114 str = 1.2@myhost:2345 115 116 op1(str) = ( "1.2" "myhost:2345" ) 117 118 define splice( int index, Operator op ) on a list of strings, with op( String ) : (String) 119 to replace the indexth element of a list of strings with the list returned 120 from op( element ). 121 122 compose( op1, splice( 1, op2 )) is the correct parser. 123 124 125A grammar for parsers? 126 127parser : simple_parser 128 | parser ":" simple_parser ; 129 130simple_parser : ident 131 | ident "(" param_list ")" ; 132 133param_list : param 134 | param_list "," param ; 135 136param : constant 137 | parser ; 138 139constant is a Java constant 140ident x is interpreted as either a public static method on OperationFactory 141named xAction which takes as arguments the types of the param list, or as 142the fully qualified class name of a class that implements Operation and has 143a constructor which takes as arguments the types of the param list. 144 145From parser table: 146 147debugFlags string 148ORBInitialHost string 149ORBInitialPort integer 150ORBServerHost string 151ORBServerPort integer 152orbId string 153highWaterMark integer 154lowWaterMark integer 155etc. 156 157giopVersion construct(GIOPVersion.class):map(integer):list('.') 158giopFragmentSize mod(ORBConstants.GIOP_FRAGMENT_DIVISOR):min(ORBConstants.GIOP_FRAGMENT_SIZE):integer 159 160Lisp notation: 161 parse((mod ORBConstants.GIOP_FRAGMENT_DIVISOR) (min ...) (integer)) 162 163giop11BuffMgr makeMap(map) where map is constructed in java with 164 map.get("GROW") = Integer(0) 165 map.get("CLCT") = Integer(1) 166 map.get("STRM") = Integer(2) 167 168giopTargetAddressPreference intToShort:integerRange(0,3) 169giopAddressDisposition another map variant 170 171charData construct(CodeSetComponentInfo.class):string 172 173 174What about corbaloc:? 175 176v12 = GIOPVersion.v12 ; 177 178giopVersion = construct( GIOPVersion.class ):mapSequence( [integer,integer] ):FSR(".") 179 180iiopAddress = mapSequence( [giopVersion,identity,integer] ): 181 splice( 1, LSR( ":" 9090 )): 182 FSR( "@", v12 ) 183 184addressHandler = choice( 185 "iiop:", iiopAddress 186 ":", iiopAddress 187) 188 189addressList = map(addressHandler):SL(",") 190 191choice( 192 "corbaloc:", mapSequence( [addressList,string] ):RSL("/", "NameService"), 193 "corbaname:", ... 194) 195