Parsing - primtive types - lists of various sorts Basic models prefix A,BCDF scans left-to-right suffix ABCD:F scans right-to-left Model 1: data is sep,op,next,combine if (sep found in data) split data into prefix, rest return combine( op(prefix), next(rest) ) else return combine( default, next(data) ) pop = suffix1( ":", op3, op4, ++ ) op = prefix1( ",", op2, pop, ++ ) op( A,BDF.FGH:Z ) = op2(A) ++ pop( BDF.FGH:Z ) = op2(A) ++ op4( BDF.FGH ) ++ op3( Z ) Model 2: data is sep,op,next,combine if (sep found in data) split data into prefix, rest return combine( op(prefix), next(rest) ) else return op(data) example op = prefix2( ":", op2, null, ++ ) op.setNext( op ) ; op( A:B:C:D ) = op2(A) ++ op2(B) ++ op2(C) ++ op2(D) reduce( sep, initial, op, combine ) operate( data ) if (sep in data) split data into prefix, rest return combine( op(prefix), operate( rest )) else return combine( op(data), initial ) reduce( sep, op1, op2, initial, combine ) operate(data) if (sep in data) // either first from left orfirst from right split data into prefix, rest return combine( op1( prefix ), op2( rest ) ) else return opx( data ) type class combine init : X add( X, Y ) : X op1( String ) : X op2( String ) : Y reduce( sep, op1, op2, comb ) ( String ) : X operate(data) if (sep in data) // either first from left orfirst from right split data into prefix, rest return comb.add( op2.operate( rest ), op1.operate( prefix ) ) else return comb.add( comb.init(), op1.operate( data ) ) example op = reduce( ":", op1, null, comb ) op.setop2( op ) op.operate( "A:B:C" ) = comb.add( op.operate( "B:C" ), op1.operate( "A" ) ) = comb.add( comb.add( op.operate("C"), op1.operate("B") ), op1.operate( "A" ) = comb.add( comb.add( comb.add( comb.init(), op1.operate("C") ), op1.operate("B") ), op1.operate("A") ) Splitter interface interface Splitter { List split( String str ) } variations: - separated list SL - first sep rest FSR - fail if not present one arg - default value two args - rest sep last RSL - fail if not present one arg - default value two args Have we just pushed the real problem off a level? How do we combine: op1 = FSR("@",v12) op2 = LSR(":",9090) str = 1.2@myhost:2345 op1(str) = ( "1.2" "myhost:2345" ) define splice( int index, Operator op ) on a list of strings, with op( String ) : (String) to replace the indexth element of a list of strings with the list returned from op( element ). compose( op1, splice( 1, op2 )) is the correct parser. A grammar for parsers? parser : simple_parser | parser ":" simple_parser ; simple_parser : ident | ident "(" param_list ")" ; param_list : param | param_list "," param ; param : constant | parser ; constant is a Java constant ident x is interpreted as either a public static method on OperationFactory named xAction which takes as arguments the types of the param list, or as the fully qualified class name of a class that implements Operation and has a constructor which takes as arguments the types of the param list. From parser table: debugFlags string ORBInitialHost string ORBInitialPort integer ORBServerHost string ORBServerPort integer orbId string highWaterMark integer lowWaterMark integer etc. giopVersion construct(GIOPVersion.class):map(integer):list('.') giopFragmentSize mod(ORBConstants.GIOP_FRAGMENT_DIVISOR):min(ORBConstants.GIOP_FRAGMENT_SIZE):integer Lisp notation: parse((mod ORBConstants.GIOP_FRAGMENT_DIVISOR) (min ...) (integer)) giop11BuffMgr makeMap(map) where map is constructed in java with map.get("GROW") = Integer(0) map.get("CLCT") = Integer(1) map.get("STRM") = Integer(2) giopTargetAddressPreference intToShort:integerRange(0,3) giopAddressDisposition another map variant charData construct(CodeSetComponentInfo.class):string What about corbaloc:? v12 = GIOPVersion.v12 ; giopVersion = construct( GIOPVersion.class ):mapSequence( [integer,integer] ):FSR(".") iiopAddress = mapSequence( [giopVersion,identity,integer] ): splice( 1, LSR( ":" 9090 )): FSR( "@", v12 ) addressHandler = choice( "iiop:", iiopAddress ":", iiopAddress ) addressList = map(addressHandler):SL(",") choice( "corbaloc:", mapSequence( [addressList,string] ):RSL("/", "NameService"), "corbaname:", ... )