#
#	STANDARDISE ADDRESSES TO "PAF" FORMAT
#
#	Generic file, to be included by other files,
#		the heart of the Geocode grammar file.
#	The including file must:
#		Define output fields
#		Define output fields or variables with the names of the PAF fields
#		Conclude the POST_PARSE section
#
#	Based on DpidGrammar.txt For AMAS 2004
#
############################################################
##	SUGGESTED USER MODIFIABLE LINES are marked with @@@
############################################################
#
#	[Best view with tab spacing 4]

\SUB_GRAMMARS
ArfEnhancer	ArfEnhancer.grm

# output fields before formatting (have underscore at end)
\VARIABLES
3	State_
4 	Pcode_
46 	Locality_
30	StreetName_
4	StreetType_
2	StreetSuffix_
11	PostalType_
14	AddressId_
10	HouseNo1_
2	HouseSuffix1_
10	HouseNo2_
2	HouseSuffix2_
7	FlatType_
10	FlatNo_
2	LevelType_
10	LevelNo_
45	BuildingName1_
30	BuildingName2_
10	LotNo_
10	PostalNo_
3	PostalPrefix_
3	PostalSuffix_
#others (returned from AllocateDpid)
1	PrimaryPointFlag_
1	SynonymFlag_
46	Synonym_
1	FinalAddressFlag_
46	BorderName_
4	BorderPostcode_
30	AltStName_
4	AltStType_
2	AltStSuf_
8	LocalityDID_
8	GroupDID_
10	Flag_	# amended or error and why
30	AmendedFlag_ # how amended (or more detail on error flag)
100	DummyPre     # returned from ArfEnhancer, not returned from iPaf32
100	DummyPost    # "
1	Dummy3
1	Dummy4
12	Latitude_
12	Longitude_
10	GIFlags_	# from where GIF fields taken
20	GIField1
20	GIField2
20	GIField3
20	GIField4
20	GIField5
20	GIField6

#others cont.
100	PreAddress1_
100	PreAddress2_
100	PostAddress_
37	Barcode37_
100	FoundFullLocality
100	sPafError
10	sInputFlatType
10	sInputFlatNo
4	sPostcode

1	ExtraInputs # dummy positioner for array begining
2	sFlag
	sLocality2
	sStreetType2
	sFullStreetName
# not used anymore
1	Reliability_

# abbreviations provided in the PAF files
\INCLUDE Code.txt

\IFDEF USENONPAFARF
	\TABLE localities
		\INCLUDE GnafLocalities.txt

	# these localities can get confused with street types, so only accept as locality if:
	#	a)exact spelling OR b)not divided from other locality information (pcode & state)
	\TABLE LocalitiesLikeStreetTypesTable
		\INCLUDE GnafLocalitiesLikeStreetTypes.txt

	\TABLE NumericStreetNamesTable
		\INCLUDE GnafNumericStreetNames.txt

\ELSE
	\TABLE localities
		\INCLUDE Localities.txt

	\TABLE LocalitiesLikeStreetTypesTable
		\INCLUDE LocalitiesLikeStreetTypes.txt

	\TABLE NumericStreetNamesTable
		\INCLUDE NumericStreetNames.txt

\ENDIF

\TABLE locToPcodeTable
	\INCLUDE LocToPcodeNonPostal.txt

# locality prefixes and suffixes
\TABLE auxilliaryLocalityWords
NORTH
SOUTH
EAST
WEST
N=NORTH
S=SOUTH
E=EAST
W=WEST
NTH=NORTH
STH=SOUTH
WST=WEST

\TABLE postAuxilliaryLocalityWords
BC
B C=BC
BUSINESS CENTRE=BC
DC
D C=DC
DELIVERY CENTRE=DC
LPO
L P O=LPO
MC
M C=MC
MAIL CENTRE=MC
MILPO
PO
POST OFFICE=PO
MDC
M D C=MDC
MAIL DELIVERY CENTRE=MDC
#GPO PRIVATE BOXES
#PRIVATE BOXES
HEIGHTS
HTS=HEIGHTS
JUNCTION
JNCT=JUNCTION
# TODO? add these?
#PARK
#VIEW
#GARDENS


\TABLE ordinals
1ST=FIRST
2ND=SECOND
3RD=THIRD
4TH=FOURTH
5TH=FIFTH
6TH=SIXTH
7TH=SEVENTH
8TH=EIGHTH
9TH=NINTH
10TH=TENTH
11TH=ELEVENTH
12TH=TWELFTH
13TH=THIRTEENTH
14TH=FOURTEENTH
15TH=FIFTEENTH
16TH=SIXTEENTH
17TH=SEVENTEENTH
18TH=EIGHTEENTH
19TH=NINTEENTH
20TH=TWENTIETH
21ST=TWENTYFIRST
22ND=TWENTYSECOND
23RD=TWENTYTHIRD
24TH=TWENTYFOURTH
25TH=TWENTYFIFTH
26TH=TWENTYSIXTH
27TH=TWENTYSEVENTH
28TH=TWENTYEIGHTH
29TH=TWENTYNINTH
32ND=THIRTYSECOND

\TABLE ordinals2
FIRST=1
SECOND=2
THIRD=3
FOURTH=4
FIFTH=5
SIXTH=6
SEVENTH=7
EIGHTH=8
NINTH=9
TENTH=10

\TABLE lot
LOT

\TABLE via
VIA

\TABLE careof
CARE OF=C/-
C/O=C/-
C/=C/-
C-=C/-
C/-

# building types (1-with name before, 2-without)
\TABLE building_types1
#taken from looking at PAF building names
ACADEMY
AGED CARE
APARTMENTS
APTS
ARCADE
BLDG
BUILDING
CAMPUS
CHILD CARE
CARAVAN PARK
CENTRE
CHILDCARE
CHURCH
CLUB
CENTR=CENTRE
CNTR=CENTRE
CNTRE
COLLEGE
COMPLEX
COURT
COURTS
DAY CARE
FARM
FLATS
#HOME
HOME FOR THE AGED
HOME FOR AGED
#HOSTEL
HOSPITAL
#HOTEL
#HOUSE
INN
KINDER
KINDERGARTEN
KINDY
LODGE
#LPO
MOTEL
PARK
PLACE
PLAZA
POST OFFICE
PRE SCH
PRE-SCHOOL
PRESCHOOL
PRIMARY
PRIMARY SCH
RESORT
SCHOOL
STATION
TAFE
UNITS
UNIVERSITY
VILLAGE
ZOO

#added - not from the paf
ARC=ARCADE
CHAMBERS
CIAO
CT=COURT
ESTATE
GARDENS
GDNS=GARDENS
HALL
HOME
HOSTEL
HOTEL
HOUSE
MALL
MEWS
PL=PLACE
RANCH
RESTAURANT
S C=SHOPPING CENTRE
TOWER
TOWERS
TWRS=TWRS
\IFDEF _EA_
SHOPPINGTOWN
\ENDIF

\TABLE building_types2
#not from the PAF
HOUSE
VILLAGE
FARM
GLEN
LODGE
RANCH
RESIDENCE
BRAE
MEWS
BLK
\IFDEF _EA_
WESTFIELD
\ENDIF

\TABLE sureLevelTypesTable
LEVEL=L
FLOOR=FL

\TABLE sureLevelType3Table
BASEMENT=B
GROUND FLOOR=G
LOWER GROUND FLOOR=LG
MEZZANINE=M
UPPER GROUND FLOOR=UG

\TABLE sureUnitTypesTable
APARTMENT=APT
FLAT=F
SUITE=SE
SHOP
UNIT=U


#gives a problem as cofuses with the postal type RSD (is this still true?)
\TABLE ballaratRSD
BALLARAT ROADSIDE DELIVERY

\VARIABLES
sLoc
sL1
sL2
sL3
sDummy
255	sTemp
255	sFullPaf
1	sDelim
sCareof
3	sVia
100	sPreAddress
10	sTrim
sFullStreetSuffix
sFullStreetType2
sTempPcode
sTempStreetType
sTempLot
sBuildingName
7	sSureUnitType
10	sSureUnitNo
2	sSureLevelType
10	sSureLevelNo
100	sId

\NUMERIC_VARIABLES
bSecondLocality
i
j
iPafError
iFlag
iNumARFFields

#\PRE_PARSE {
	#sDelim = "	"
#	INPUT = UCASE(INPUT) }

\CONSTANTS
		# TODO include \v
	allPunctuation = " `~!@#$%^&*()-_+=\\|{}[]:'\";<>?,./\t\n\r\f"
		# TODO - why don't allow these punctuation marks?
	baseDelimiters = allPunctuation - "`~_\\|"
	numbers = "1234567890"
	baseDelimitersNumbers = numbers + baseDelimiters
	nonDividingDelimiters = baseDelimiters - expectedDivider
	wordDelimiters = " \t.-&'/" - expectedDivider
		# street number cannot use dash, as it's used between street numbers
	streetNumDelimiters = baseDelimiters - "-"
		# appostrophe and dash used in names
	nameDelimiters = baseDelimiters - "'-"
		# /- used in care of
	careofDelimiters = baseDelimiters - "/-"
		# TODO why dont allow these punctuation
	streetAddressDelimiters = baseDelimiters - expectedDivider - "%&;<>"
		# cannot have names divided over two lines
	innerNameDelimiters = nameDelimiters - expectedDivider
		# TODO: why no appostophe?
	stateDelimiters = baseDelimitersNumbers - "'"
		# these two are used in post box type names (eg. C/- P O)
	pbtypeDelimiters = baseDelimitersNumbers - "/-"
		# don't know why using these only
	localityDelimiters = "\t ()-{}[]:'./" - expectedDivider
		# character sets
	letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	pbtypeCharset = letters + "/-"

\DLL iPaf32.dll
\IFDEF WANT_SORTPLANS
	INITFUNC OpenPaf	NONZERO_ERROR CONTINUE
	FINALFUNC ClosePaf
	PostcodeToBsp		NONZERO_ERROR	ONERROR RETURN "" ONINITERROR RETURN ""
	PostcodeToNpsp		NONZERO_ERROR	ONERROR RETURN "" ONINITERROR RETURN ""
\ENDIF
	CallPafFromStan		NONZERO_ERROR TO iPafError
	GetDpid				NONZERO_ERROR TO iPafError
	GetDpidNonAmas		NONZERO_ERROR TO iPafError
	DpidToBarcode		ONERROR RETURN ""	NONZERO_ERROR


# ---------- name of ARF specified in grammar file
\IFDEF sARF_NAME

\GLOBAL_VARIABLES
sGlobalArfId
sGlobalArfId2

\INITIALIZE {
	#open the ARF to ensure that it stays open for the life time of the grammar
	sTemp = "OpenArf;Database=" + sARF_NAME
	sTemp = sTemp + ";"
	sGlobalArfId = CallPafFromStan(sTemp)
	# an error sets iPafError to non-zero or sGlobalArfId to "Error..."
	IF iPafError = 0
		sTemp = LEFT(sGlobalArfId, 5)
		IF sTemp = "Error"
			sGlobalArfId = ""
		END IF
	END IF

\IFDEF sARF_NAME2
	sTemp = "OpenArf;Database=" + sARF_NAME2
	sTemp = sTemp + ";"
	sGlobalArfId2 = CallPafFromStan(sTemp)
	# an error sets iPafError to non-zero or sGlobalArfId to "Error..."
	IF iPafError = 0
		sTemp = LEFT(sGlobalArfId2, 5)
		IF sTemp = "Error"
			sGlobalArfId2 = ""
		END IF
	END IF
\ENDIF #sARF_NAME2
}

\FINALIZE {
	IF sGlobalArfId <> ""
		sTemp = "CloseArf;Id=" + sGlobalArfId
		sTemp = sTemp + ";"
		CallPafFromStan(sTemp)
	END IF

\IFDEF sARF_NAME2
	IF sGlobalArfId2 <> ""
		sTemp = "CloseArf;Id=" + sGlobalArfId2
		sTemp = sTemp + ";"
		CallPafFromStan(sTemp)
	END IF
\ENDIF #sARF_NAME2
}

\ENDIF #sARF_NAME
# ----------


\GRAMMAR
# locality
AuxLoc		: TABLE auxilliaryLocalityWords TOLERANCE1 4
PostAuxLoc	: TABLE postAuxilliaryLocalityWords TOLERANCE1 6
Via			: TABLE via
			# for AMAS 2003, ignoring all punctuation in locality names
Locality	: TABLE localities !  DELIMITERS baseDelimiters TOLERANCE2 2	\
			INNER_DELIMITERS nonDividingDelimiters
			: TABLE_SINGLE_WORDS LocalitiesLikeStreetTypesTable ! DELIMITERS baseDelimiters
BallaratRSD	: TABLE ballaratRSD !  DELIMITERS baseDelimiters TOLERANCE2 5	\
			INNER_DELIMITERS nonDividingDelimiters
LocalityST	: TABLE_SINGLE_WORDS LocalitiesLikeStreetTypesTable ! DELIMITERS baseDelimiters \
			TOLERANCE2 2

Locality1	: Locality(sDummy sL1) AuxLoc(sDummy sL2) PostAuxLoc?(sDummy sL3) \
				DELIMITERS localityDelimiters
			{	sLoc = sL1 & sL2
				sLoc = sLoc & sL3
				IF bSecondLocality = 0
					Locality_ = sLoc
					bSecondLocality = 1
				ELSE
					sLocality2 = sLoc
				END IF
			}
			: AuxLoc(sDummy sL1) Locality(sDummy sL2) PostAuxLoc?(sDummy sL3) \
				DELIMITERS localityDelimiters
			{	AS_ABOVE	}
			: Locality(sDummy sL1) PostAuxLoc?(sDummy sL2) DELIMITERS localityDelimiters
			{	sLoc = sL1 & sL2
				IF bSecondLocality = 0
					Locality_ = sLoc
					bSecondLocality = 1
				ELSE
					sLocality2 = sLoc
				END IF
			}
Locality2	: Locality1 Via?(sVia) Locality1
State		: TABLE states ! DELIMITERS stateDelimiters
Pcode		: NUMBER_RANGE 800 9999 !
			# NUMBER_SIZE_RANGE 4 !	# REPLACED BY ABOVE
			: NUMBER_RANGE 200 299 !
			# incase state appears twice in input string
FullLocality: Pcode(sTempPcode) Locality1 State?(State_) State? ~
			{ Pcode_ = RIGHT(sTempPcode, 4)	} # incase post code has leading zeros
			: Pcode(sTempPcode) LocalityST(sDummy Locality_) State?(State_) ~ DELIMITERS localityDelimiters
			{	AS_ABOVE	}
			: Pcode(sTempPcode) Locality1? State?(State_) State? ~
			{	AS_ABOVE	}
			: Locality1 State?(State_) ~
			: LocalityST(sDummy Locality_) State?(State_) ~ DELIMITERS localityDelimiters
			: State(State_) ~
FullLocalty2: Pcode(sTempPcode) Locality2 State?(State_) State? ~
			{ Pcode_ = RIGHT(sTempPcode, 4)	} # incase post code has leading zeros
			: Pcode(sTempPcode) LocalityST(sDummy Locality_) State?(State_) ~ DELIMITERS localityDelimiters
			{	AS_ABOVE	}
			: Pcode(sTempPcode) Locality2? State?(State_) State? ~
			{	AS_ABOVE	}
			: Locality2 State?(State_) ~
			: LocalityST(sDummy Locality_) State?(State_) ~ DELIMITERS localityDelimiters
			: State(State_) ~
# pobox
PbType1		: TABLE postal_delivery_type1 DELIMITERS pbtypeDelimiters
PbType2		: TABLE postal_delivery_type2 DELIMITERS pbtypeDelimiters
PbType3		: TABLE postal_delivery_type3 DELIMITERS baseDelimitersNumbers
Char123		: WORD_SIZE_RANGE 1 2
			: "SEO"	<> DELIMITERS baseDelimitersNumbers # to be update with PAF releases
			: "BZB" <> DELIMITERS baseDelimitersNumbers # "
Num			: NUMBER
PoboxNum	: Num(PostalNo_) Char123?(PostalSuffix_) DELIMITERS "" # ensure no space between number & suffix
Pobox		: PbType1(PostalType_) Char123?(PostalPrefix_) PoboxNum DELIMITERS streetAddressDelimiters
			: PbType3(PostalType_) Char123?(PostalPrefix_) PoboxNum DELIMITERS streetAddressDelimiters
			: PbType2(PostalType_)
			: PbType3(PostalType_)
# street name
Word		: WORD2
Words		: Word? Word Word Word DELIMITERS wordDelimiters
			: Word? Word DELIMITERS wordDelimiters
			: TABLE ordinals
StreetType	: TABLE street_types_multiple_words TOLERANCE1 2
				# nameDelimiters added for AMAS test 3
			: TABLE_SINGLE_WORDS street_types DELIMITERS nameDelimiters
StreetSuffix: TABLE street_suffixes
NumStreet	: TABLE NumericStreetNamesTable DELIMITERS nameDelimiters
StreetName	: Words(StreetName_) StreetType(sStreetType2 sFullStreetType2) \
				StreetType(StreetType_ sTempStreetType) \
				StreetSuffix(StreetSuffix_ sFullStreetSuffix) \
				DELIMITERS streetAddressDelimiters
			{
				# Name="The" Type="Avenue" -> Name="The Avenue"
				IF StreetName_ = "THE"
					IF sFullStreetType2 <> ""
						StreetName_ = StreetName_ & sFullStreetType2
						sFullStreetType2 = ""
						sStreetType2 = ""
					ELSE
						StreetName_ = StreetName_ & sTempStreetType
						sTempStreetType = ""
						StreetType_ = ""
					END IF						
				END IF
				# "High Street Road" ->
				#	Name="High Street"; Type="RD"; Type2="ST"
				StreetName_ = StreetName_ & sFullStreetType2
				# create full street name for dpid allocation
				#	in case of eg. "THE STRAND EAST"
				sFullStreetName = StreetName_
				sFullStreetName = sFullStreetName & sTempStreetType
				sFullStreetName = sFullStreetName & sFullStreetSuffix
			}
			: Words(StreetName_) StreetType(StreetType_ sTempStreetType) \
				StreetSuffix(StreetSuffix_ sFullStreetSuffix) \
				DELIMITERS streetAddressDelimiters
			{	AS_ABOVE	}
			: Words(StreetName_) StreetType(sStreetType2 sFullStreetType2) \
				StreetType(StreetType_ sTempStreetType) \
				DELIMITERS streetAddressDelimiters
			{	AS_ABOVE	}
			: Words(StreetName_) StreetType(StreetType_ sTempStreetType) \
				DELIMITERS streetAddressDelimiters
			{	AS_ABOVE	}
			: NumStreet(StreetName_) StreetType?(StreetType_ sTempStreetType) \
				DELIMITERS streetAddressDelimiters
			{	AS_ABOVE	}
# units
Char1		: WORD_SIZE_RANGE 1 1
Slash		: "/"
UnitType	: TABLE flat_unit_type CHAR_SET letters TOLERANCE1 6 <
			# insures no gap between unit number and suffix (19Sept00)
UnitNo		: Num Char1? DELIMITERS ""
			: Char1
Unit		: UnitType(FlatType_) UnitNo(FlatNo_)
UnitSlash	: Unit Slash
			: UnitNo(FlatNo_) Slash
SureUnitType: TABLE sureUnitTypesTable CHAR_SET letters <
SureUnit	: SureUnitType(sSureUnitType) UnitNo(sSureUnitNo)

#levels
Ordinal2	: TABLE ordinals2
			: ORDINAL
LevelType1	: TABLE building_level_type1 CHAR_SET letters <
LevelType2	: TABLE building_level_type2 CHAR_SET letters <
LevelType3	: TABLE building_level_type3 CHAR_SET letters <
			# these two were removed from table, so picked up here
			: $ "B" >
			: $ "M" >
LevelType4	: TABLE building_level_type4 CHAR_SET letters <
Level		: Ordinal2(LevelNo_) LevelType1(LevelType_)
			: LevelType4(LevelType_) UnitNo(LevelNo_)
			: LevelType1(LevelType_) UnitNo(LevelNo_)
			: LevelType2(LevelType_) UnitNo(LevelNo_)
			: LevelType3(LevelType_) UnitNo?(LevelNo_)
			# (AMAS2002:) missing number
			: LevelType1(LevelType_)
			: LevelType2(LevelType_)
SureLvlType	: TABLE sureLevelTypesTable CHAR_SET letters <
SureLvlType3: TABLE sureLevelType3Table CHAR_SET letters <
SureLevel	: SureLvlType(sSureLevelType) UnitNo(sSureLevelNo)
			: SureLvlType3(sSureLevelType) UnitNo?(sSureLevelNo)

# building name
BuildingType1: TABLE building_types1 TOLERANCE2 5
BuildingType2: TABLE building_types2 TOLERANCE2 5
Building	: Words BuildingType1
			: BuildingType2

# street number
Dash		: "-"
LOT			: TABLE lot CHAR_SET letters <
Lot			: LOT Num(LotNo_) Char1?(sTempLot)
			{	LotNo_ = LTRIM(LotNo_, "0")
				LotNo_ = LotNo_ + sTempLot	}
# DELIMITERS clause will put the W in "10 W Lindsey Rd" with the street name
StreetNum	: Lot
			: Num(HouseNo1_) Char1?(HouseSuffix1_) Dash\
				Num(HouseNo2_) Char1?(HouseSuffix2_)	DELIMITERS ""
			: Num(HouseNo1_) Dash Num(HouseNo2_) DELIMITERS " " #eg. "321 - 325" (added 20/03/02)
			: Num(HouseNo1_) Char1?(HouseSuffix1_)	DELIMITERS ""
FullStreetNum: Lot? Unit Level StreetNum ~ DELIMITERS streetNumDelimiters
			# "Lot?" added to pick up invalid address having both lot# & street#
			: Lot? Level UnitSlash? StreetNum DELIMITERS streetNumDelimiters
			: Lot? UnitSlash? StreetNum Level
			# to pick up invalid "Unit 1-5 main st"
			#: Lot? Unit Dash StreetNum
			: Lot? Unit StreetNum ~ DELIMITERS streetNumDelimiters
			# don't have "-" in delimiters, because "Unit 1-5 Main St"
			: Lot? UnitSlash StreetNum
			#: Lot (moved to be part of StreetNum 29/6/00)
			: Lot? StreetNum
			# @@@ use next line to allow unit without slash (eg 1 5 main st = 1/5 main st)
			: UnitNo(FlatNo_) StreetNum
UnitOrLevel	: Level Unit? ~
			: Unit
			# delimiters to ensure streetNo and name on same address line (no comma inbetween)
StNumAndName: FullStreetNum StreetName DELIMITERS streetAddressDelimiters
# full address
StreetAddr	: UnitOrLevel Building(BuildingName1_) FullStreetNum StreetName
# @@ to give preference to building names use the next line
#			: UnitOrLevel Building(BuildingName1_)
			: StNumAndName UnitOrLevel? Building?(BuildingName1_) ~
			: Building?(BuildingName1_) StreetName
			: Building(BuildingName1_)
			: FullStreetNum Words(StreetName_) UnitOrLevel? DELIMITERS streetAddressDelimiters
CareOf		: $ TABLE careof DELIMITERS careofDelimiters
			# ensure /- not delimiters
Full_addr	: $ BallaratRSD?(sDummy Locality_) Pobox? \
				FullLocality?(FoundFullLocality) StreetAddr? $ ~
			: $ BallaratRSD?(sDummy Locality_) Pobox? \
				FullLocalty2?(FoundFullLocality) StreetAddr? $ ~
			# @@@ Use next line to pick up "c/o" at address beginning. Else use line below it
			#: BallaratRSD?(sDummy Locality_) Pobox? FullLocality?(FoundFullLocality) StreetAddr? CareOf?(sCareof) @ ~
			: BallaratRSD?(sDummy Locality_) Pobox?	\
				FullLocality?(FoundFullLocality) StreetAddr? SureLevel? SureUnit? @ ~
		{	sTrim = " \t,"
			sPreAddress = SUB_INPUT_FOUND(0, -1)
			sPreAddress = RTRIM(sPreAddress, " \t\r\n,")
			#IF sCareof <> ""
			#	sTemp = SUB_INPUT_FOUND(1, -2)
			#	sTemp = LTRIM(sTemp, " :")
			#	sTemp = RTRIM (sTemp, sTrim)
			#	sCareof = sCareof & sTemp
			#ELSE
				PostAddress_ = SUB_INPUT_FOUND (1, -2)
				PostAddress_ = TRIM(PostAddress_, sTrim)
			#END IF
			# get extra info on line, not picked up
			sTemp = SUB_INPUT_FOUND(2, -3)
			sTemp = TRIM(sTemp, sTrim)
			PostAddress_ = PostAddress_ & sTemp
			sTemp = SUB_INPUT_FOUND(3, -4)
			sTemp = TRIM(sTemp, sTrim)
			PostAddress_ = PostAddress_ & sTemp
			sTemp = SUB_INPUT_FOUND(4, -5)
			sTemp = TRIM(sTemp, sTrim)
			PostAddress_ = PostAddress_ & sTemp
			sTemp = SUB_INPUT_FOUND(5)
			sTemp = TRIM(sTemp, sTrim)
			PostAddress_ = PostAddress_ & sTemp
			PostAddress_ = TRIM(PostAddress_, "\n\r\t ,")
			# split pre address by carriage returns or tabs
			i = INSTR(sPreAddress, "\n")
			IF i <= 1
				i = INSTR(sPreAddress, "\t")
			END IF
			IF i <= 1
				PreAddress1_ = sPreAddress
			ELSE
				i = i - 1
				PreAddress1_ = LEFT(sPreAddress, i)
				i = i + 2
				PreAddress2_ = MID(sPreAddress, i)
			END IF
			# insert level or unit found
			IF LevelType_ = ""
				LevelType_ = sSureLevelType
				LevelNo_ = sSureLevelNo
			END IF
			IF FlatNo_ = ""
				FlatType_ = sSureUnitType
				FlatNo_ = sSureUnitNo
			END IF
		}
#Full_addr	: Pobox? StreetAddr? FullLocality(FoundFullLocality) @
#			: Pobox? StreetAddr? @
#Full_addr	: $ Pobox? FullLocality?(FoundFullLocality) StreetAddr? $ ~010
#			: Pobox? FullLocality?(FoundFullLocality) StreetAddr? @ ~010

\POST_PARSE {

	sDelim = "\t"

# add VIA to second locality (if eg. "UKI VIA MURWILLUMBAH")
	IF sLocality2 <> ""
		sLocality2 = sVia & sLocality2
	END IF

# fix for state getting picked up as locality (eg "WA" as locality "WAY")
	IF State_ = ""
		sTemp = LOOKUP(Locality_, states)
		IF sTemp <> ""
			State_ = sTemp
			Locality_ = ""
		END IF
	END IF

# Look up dpid
\IFNDEF SKIP_DPID_LOOKUP
		# save building name, as gets over-written
		sBuildingName = BuildingName1_
		sInputFlatType = FlatType_
		sInputFlatNo = FlatNo_
		# @@@ sFlag determines what part of the input address to leave unchanged
		#  1=keep unit/level information when can only match to primary point
		#  2=keep street name in postal address
		#  4=keep locality name if a valid synonym
		#  8=keep locality name if a locality of this name exists within this postcode or border
		#(16=keep incorrect street type and suffix (if not ambiguous)) - not yet implemented
		# 32=keep alternate street name
		# these values can be added (bitwise OR) to combine options
		sFlag = "63" # for STF use 3, else use 63
		# store postcode, as there are no postcodes in GNAF
		sPostcode = Pcode_
		# call iPaf32.GetDpid
		sFullPaf = JOIN(State_, 22, sDelim)
		sTemp = JOIN(ExtraInputs, 5, sDelim)
		sFullPaf = sFullPaf + sTemp

		# open the required ARF
		sTemp = "OpenArf;Database="
		sTemp = sTemp + sDatabase
		sTemp = sTemp + ";"
		iPafError = 0
		sId = CallPafFromStan(sTemp)
		sTemp = LEFT(sId, 5)
		# check for error
		IF iPafError <> 0
			sPafError = STR(iPafError)
			sPafError = "Opening ARF error: " + sPafError
		ELSEIF sTemp = "Error"
			sPafError = sId
		ELSE
			sId = "Id=" + sId
			sId = sId + ";"

			IF sGIFields <> ""
				# tell iPaf32 which GCs we want
				sTemp = "SetGeographicalCodes;" + sId
				sTemp = sTemp + sGIFields
				sTemp = CallPafFromStan(sTemp)
				IF iPafError <> 0
					sPafError = STR(iPafError)
					sPafError = "SetGeographicalCodes error: " + sPafError
				END IF
			END IF

			# lookup address with this ARF
			sTemp = "LookupAddress;" + sId
			sFullPaf = sTemp + sFullPaf
			sFullPaf = CallPafFromStan(sFullPaf)
			IF iPafError <> 0
				sPafError = STR(iPafError)
				sPafError = "Address lookup error: " + sPafError
			END IF
			# close ARF
			sTemp = "CloseArf;" + sId
			sTemp = CallPafFromStan(sTemp)
		END IF

		#
		sTemp = LEFT(sFullPaf, 1)
		# error
		IF sPafError <> ""
			Flag_ = "E"
		# there is a returned address
		ELSEIF sTemp <> sDelim
			State_ = SPLIT(sFullPaf, 48, sDelim)

			# Calculate Barcode
\IFDEF DontPutDidInDpid
			IF AddressId_ <> ""
				Barcode37_ = DpidToBarcode(AddressId_)
			ELSEIF GroupDID_ <> ""
				Barcode37_ = DpidToBarcode(GroupDID_)
			ELSEIF LocalityDID_ <> ""
				Barcode37_ = DpidToBarcode(LocalityDID_)
			END IF
\ELSE
			# put DID in DPID if appropriate. Calculate Barcode
			IF AddressId_ = ""
				IF GroupDID_ <> ""
					AddressId_ = GroupDID_
				ELSE
					AddressId_ = LocalityDID_
				END IF
			END IF
			IF AddressId_ <> ""
				Barcode37_ = DpidToBarcode(AddressId_)
			END IF
\ENDIF
		ELSE
			# get reason for no match (fields 34 & 35)
			# and other fields (mainly GIF: fields 43-47)
			i = 1
			FOR j = 1 TO 33
				i = INSTR(sFullPaf, sDelim, i)
				i = i + 1
			NEXT
			sTemp = MID(sFullPaf, i)
			Flag_ = SPLIT(sTemp, 15, sDelim)
		END IF
		# restore building name
		IF BuildingName1_ = ""
			BuildingName1_ = sBuildingName
		# put it somewhere else
		ELSE
			i = INSTR(BuildingName1_, sBuildingName)
			IF i = 0
				IF PreAddress1_ = ""
					PreAddress1_ = sBuildingName
				ELSE
					PreAddress2_ = PreAddress2_ & sBuildingName
				END IF
			END IF
		END IF
		# use input flat type, if no flat type in PAF (@@@ this section is optional)
		IF FlatNo_ <> ""
			IF FlatType_ = ""
				IF FlatNo_ = sInputFlatNo
					FlatType_ = sInputFlatType
				END IF
			END IF
		END IF


		IF iLenient = iTrue

			iFlag = VAL(Flag_, -1)
			IF iFlag < 0
				
				sTemp = sDatabase + ";"
				IF sGIFields <> ""
					sTemp = sTemp + "GIF="
					sTemp = sTemp + sGIFields
					sTemp = sTemp + ";"
				END IF
				sTemp = sTemp + INPUT
				sFullPaf = ArfEnhancer(sTemp, 1)
				# found an address (use State field - ok?)
				sTemp = LEFT(sFullPaf, 1)
				IF sTemp <> sDelim
					State_ = SPLIT(sFullPaf, 48, sDelim)
					iFlag = VAL(Flag_, -1)
					IF iFlag >= 0
						iFlag = iFlag OR 8 # amended on 2nd pass
						Flag_ = STR(iFlag)
					END IF

					# get pre and post address
					PreAddress1_ = DummyPre
					PreAddress2_ = ""
					PostAddress_ = DummyPost
					# Calculate Barcode
\IFDEF DontPutDidInDpid
					IF AddressId_ <> ""
						Barcode37_ = DpidToBarcode(AddressId_)
					ELSEIF GroupDID_ <> ""
						Barcode37_ = DpidToBarcode(GroupDID_)
					ELSEIF LocalityDID_ <> ""
						Barcode37_ = DpidToBarcode(LocalityDID_)
					END IF
\ELSE
					# put DID in DPID if appropriate. Calculate Barcode
					IF AddressId_ = ""
						IF GroupDID_ <> ""
							AddressId_ = GroupDID_
						ELSE
							AddressId_ = LocalityDID_
						END IF
					END IF
					IF AddressId_ <> ""
						Barcode37_ = DpidToBarcode(AddressId_)
					END IF
\ENDIF
					# restore building name
					IF BuildingName1_ = ""
						BuildingName1_ = sBuildingName
					# put it somewhere else
					ELSE
						i = INSTR(BuildingName1_, sBuildingName)
						IF i = 0
							IF PreAddress1_ = ""
								PreAddress1_ = sBuildingName
							ELSE
								PreAddress2_ = PreAddress2_ & sBuildingName
							END IF
						END IF
					END IF
					# use input flat type, if no flat type in PAF (@@@ optional)
					IF FlatNo_ <> ""
						IF FlatType_ = ""
							IF FlatNo_ = sInputFlatNo
								FlatType_ = sInputFlatType
							END IF
						END IF
					END IF
				END IF
			END IF
		END IF

\ENDIF # !SKIP_DPID_LOOKUP


# modification 7/2/02 - if pre address is building name -> remove it
	IF BuildingName1_ <> ""
		IF PreAddress1_ <> ""
			sTemp = BuildingName1_ & BuildingName2_
			# pre2
			IF PreAddress2_ <> ""
				# pre2
				i = INSTR(sTemp, PreAddress2_)
				IF i > 0
					PreAddress2_ = ""
				END IF
			END IF
			# pre1
			i = INSTR(sTemp, PreAddress1_)
			IF i > 0
				PreAddress1_ = PreAddress2_
				PreAddress2_ = ""
			END IF
		END IF
	END IF

# @@@ assign a postcode from table (for GNAF, which has no postcodes)
	IF Pcode_ = ""
		IF State_ <> ""
			IF Locality_ <> ""
				# only if valid result
				IF Flag_ = "0"
					iFlag = -1
				ELSE
					iFlag = VAL(Flag_)
				END IF
				IF iFlag <> 0
					temp = Locality_ + State_
					temp = LOOKUP(temp, locToPcodeTable)
					IF temp <> ""
						# modify postcode
						IF temp <> sPostcode
							# mark as amended (flag 4)
							iFlag = VAL(Flag_)
							iFlag = iFlag OR 4
							Flag_ = STR(iFlag)
							# no user's postcode
							IF sPostcode = ""
								# mark as 'amended missing Postcode'
								AmendedFlag_ = AmendedFlag_ + "f"
							ELSE
								# mark as 'amended Postcode'
								AmendedFlag_ = AmendedFlag_ + "g"
							END IF
							sPostcode = temp
						END IF
					END IF
				END IF
			END IF
		END IF
		Pcode_ = sPostcode
	END IF

# (modification 6/9/04) remove repeated Locality, State and Postcode post address
	IF PostAddress_ <> ""
		IF PostAddress_ = Pcode_
			PostAddress_ = ""
		ELSEIF PostAddress_ = State_
			PostAddress_ = ""
		ELSEIF PostAddress_ = Locality_
			PostAddress_ = ""
		END IF
	END IF

# convert pre/post address to Title Case
	PreAddress1_ = TCASE(PreAddress1_)
	PreAddress2_ = TCASE(PreAddress2_)
	PostAddress_ = TCASE(PostAddress_)
