Identifying a command within a line

Just starting out? Need help? Post your questions and find answers here.
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Identifying a command within a line

Post by Mistrel »

I have a tool that looks for command keyword on a line and changes it, i.e.: "Find all instances of Procedure and change it to ProcedureC".

This is the procedure I'm using for this. Can anyone tell if I'm missing any cases?

Code: Select all

Procedure KeyPart(string.s,keypart.s)
	If CountString(string.s,keypart.s)
		ProcedureReturn 1
	EndIf
EndProcedure

Procedure FindCommand(String.s,StringToFind.s)
	Macro fcEndCase()
		; check for comment character and endcase
		:If pos And Not KeyPart(Left(String.s,pos-1),";")
		:Exists=1: ProcedureReturn Exists
		:EndIf
	EndMacro
	String.s=LCase(String.s): StringToFind.s=LCase(StringToFind.s)
	pos=FindString(String.s,Chr(9)+StringToFind.s+Chr(9),1):fcEndCase(); (tab)string(tab)
	pos=FindString(String.s,Chr(9)+StringToFind.s+":",1):fcEndCase(); (tab)string:
	pos=FindString(String.s,Chr(9)+StringToFind.s+".",1):fcEndCase(); (tab)string.
	pos=FindString(String.s,Chr(9)+StringToFind.s+";",1):fcEndCase(); (tab)string;
	pos=FindString(String.s,":"+StringToFind.s+Chr(9),1):fcEndCase(); :string(tab)
	pos=FindString(String.s,":"+StringToFind.s+":",1):fcEndCase(); :string:
	pos=FindString(String.s,":"+StringToFind.s+".",1):fcEndCase(); :string.
	pos=FindString(String.s,":"+StringToFind.s+";",1):fcEndCase(); :string;
	pos=FindString(String.s," "+StringToFind.s+" ",1):fcEndCase(); (s)string(s)
	pos=FindString(String.s," "+StringToFind.s+":",1):fcEndCase(); (s)string:
	pos=FindString(String.s," "+StringToFind.s+".",1):fcEndCase(); (s)string.
	pos=FindString(String.s," "+StringToFind.s+";",1):fcEndCase(); (s)string;
	pos=FindString(String.s,":"+StringToFind.s+" ",1):fcEndCase(); :string(s)
	pos=FindString(String.s,Chr(9)+StringToFind.s+" ",1):fcEndCase(); (tab)string(s)
	pos=FindString(String.s," "+StringToFind.s+Chr(9),1):fcEndCase(); (s)string(tab)
	pos=Left(String.s,Len(StringToFind.s)+1)=StringToFind.s+Chr(9):fcEndCase(); |string(tab)
	pos=Left(String.s,Len(StringToFind.s)+1)=StringToFind.s+" ":fcEndCase(); |string(s)
	pos=Left(String.s,Len(StringToFind.s)+1)=StringToFind.s+":":fcEndCase(); |string:
	pos=Left(String.s,Len(StringToFind.s)+1)=StringToFind.s+".":fcEndCase(); |string.
	pos=Left(String.s,Len(StringToFind.s)+1)=StringToFind.s+";":fcEndCase(); |string;
	pos=Right(String.s,Len(StringToFind.s)+1)=Chr(9)+StringToFind.s:fcEndCase(); (tab)string(crlf)
	pos=Right(String.s,Len(StringToFind.s)+1)=" "+StringToFind.s:fcEndCase(); (s)string(crlf)
	pos=Right(String.s,Len(StringToFind.s)+1)=":"+StringToFind.s:fcEndCase(); :string(crlf)
	If String.s=StringToFind.s; |string(crlf)
		Exists=1
	EndIf
	ProcedureReturn Exists
EndProcedure
Last edited by Mistrel on Wed Jan 16, 2008 9:34 pm, edited 1 time in total.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

"Find all instances of Procedure and change it to ProcedureC"
Have you tried ReplaceString()?
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

> Have you tried ReplaceString()?

No good if he wants to replace just the word "Procedure":

"ProcedureReturn 1" would become "ProcedureC 1"
"ProcedureDLL" would become "ProcedureC"

and so on.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
#NULL
Addict
Addict
Posts: 1499
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

Post by #NULL »

you can replace "Procedure "
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

> you can replace "Procedure "

That won't work with Procedure.s, Procedure.l, etc; but I guess there's
nothing stopping replacing "Procedure." with "ProcedureC." though. :)
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Dare
Addict
Addict
Posts: 1965
Joined: Mon May 29, 2006 1:01 am
Location: Outback

Post by Dare »

:)

But Trond is basically right, unless you are writing a full blown parser of some sort.

Code: Select all

  src = ReplaceString(src,"Procedure","ProcedureC",1,1)
  src = ReplaceString(src,"ProcedureCReturn","ProcedureReturn",1,1)
  src = ReplaceString(src,"EndProcedureC","EndProcedure",1,1)
;  src = ReplaceString(src,"ProcedureCDLL","ProcedureDLL",1,1)     ; if not to be 'c'ed.

Edit:

Is it "procedure" embedded in strings and after ";" that concerns you?
Dare2 cut down to size
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Post by Mistrel »

PB wrote:> you can replace "Procedure "

That won't work with Procedure.s, Procedure.l, etc; but I guess there's
nothing stopping replacing "Procedure." with "ProcedureC." though. :)
Thanks. I forgot about the procedures with a return type. I also forgot the possibility of a trailing comment.

I've updated my the code in my first post with the changes. I think this covers every case.
superadnim
Enthusiast
Enthusiast
Posts: 480
Joined: Thu Jul 27, 2006 4:06 am

Post by superadnim »

Try using a stack, it'll open doors for other parsing options as well.
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Post by Mistrel »

superadnim wrote:Try using a stack, it'll open doors for other parsing options as well.
What would I need a stack for if I parse everything in a single pass?
User avatar
Hroudtwolf
Addict
Addict
Posts: 803
Joined: Sat Feb 12, 2005 3:35 am
Location: Germany(Hessen)
Contact:

Post by Hroudtwolf »

I recommend an lexical analysis with a tokenizer.
On big sources, it would be faster.

Example for tokenizing:

Code: Select all

MyProc (lMyVar)
; Comment

Code: Select all

Token             Typ
-------------------------------------------
MyProc         |  Identifier 
(              |  Open bracket
lMyVar         |  Identifier
)              |  Closed bracket
; Comment      |  Comment
Post Reply