nav_dugme codeBlog codeBlog
  • početna Početna stranica
  • Sačuvani članci Sačuvani članci
  • Članci
     (spisak)
  • Kontakt
Povratak na vrh stranice

Info & povezani članci Info o članku - dugme

Info

trejler_sat Datum objave: 18.09.2021.

trejler_dokument Jezici: Python

trejler_teg_narandzasti Težina: 7/10

Python
regularni izrazi
regex
optimizacija
strukture podataka
lista
obrada teksta
niske
tutorijali
saveti
zanimljivosti

Tema: Syntax highlighter

Kako napraviti syntax highlighterSyntax highlighter - Regularni izrazi u JavaScript-uTutorijal - Prepoznavanje algebarskih izraza u programskim kodovima

Povezani članci

Uvod u PythonTutorijal - Implementacija markup jezika u Python-uRegularni izrazi - napredna pretraga tekstaŠablonske niske u programskim jezicimaStrukture podatakaOperacije sa bitovima u programskom jeziku COperacije sa tekstualnim datotekama u programskim jezicima C i PythonIzbor prvog programskog jezikaASCII, Unicode i UTF - Predstavljanje znakova na računarimaGNU/Linux - 3. deo – Napredne komande
Svi članci
Don't write better error messages, write code that doesn't need them.
Jason C. McDonald

Tutorijal - Uklanjanje komentara iz programskog koda

Facebook LinkedIn Twitter Viber WhatsApp E-mail
zoom_plus zoom_minus bookmark
početna > Članci > Saveti

Uvod

Prošlim člankom započeli smo mini-serijal članaka u kojima ćemo diskutovati ("na ovaj ili onaj način"), o različitim tehnikama koje se koriste pri obradi teksta u cilju prepoznavanja delova programskih kodova.

Ovoga puta - umesto da neposredno * nastavimo tamo gde smo stali, ideje o prepoznavanju konteksta pri čitanju tokena razradićemo kroz implementaciju Python skripte za uklanjanje komentara iz programskog koda. **

Kao što smo već ustanovili u uvodnom članku, glavni zadatak tiče se pravilnog prepoznavanja i razdvajanja niski i komentara ....

* Ideje koje prikazujemo u (novom) članku, pomoći će vam da optimizujete osnovnu skriptu za "bojenje sintakse", a "usput" ćemo realizovati i nešto drugačiju samostalnu skriptu, čija je namena - uklanjanje (prepoznatih) komentara.

** Skripta je praktično namenjena C-olikim programskim jezicima kao što su C/C++, C#, Java, JavaScript, PHP i sl.

U jezicima kao što su Python i SQL, zastupljeni su samo linijski komentari koji su znatno lakši za prepoznavanje i uklanjanje, dok je prepoznavanje blok komentara u C-u i srodnim jezicima kompleksniji zahvat (koji se ne može efikasno obaviti preko regularnih izraza, i zahteva drugačiji postupak i više pažnje).

Osnovna razmatranja

Na kraju prethodnog članka razmotrili smo situaciju u kojoj na prvi pogled deluje da je pronalaženje komentara u programskom kodu trivijalan zadatak koji se može uspešno rešiti preko regularnih izraza, nalik na sledeći izraz (za linijske komentare) ....

		
//.*\n
		
	
Slika 1. - Primer "naivnog" regularnog izraza za pronalaženje linijskih komentara.

.... kao i idejno sličan regularni izraz (za blok komentare) ....

		
/\*.*\*/
		
	
Slika 2. - Primer "naivnog" regularnog izraza za pronalaženje blok komentara.

.... međutim, takođe smo se osvrnuli i na druge (dobro poznate) osobine kodnih tekstova:

  • tekst koji inače u kodu predstavlja komentar, može se naći unutar niske
  • tekst koji inače u kodu predstavlja nisku, može se naći unutar komentara

.... što dovodi do zaključka da uklanjanje komentara iz programskog koda nije "baš skroz trivijalan" zadatak.

Dovoljno je pogledati sledeći primer ....

		
#include<stdio.h>

/* --- Komentar 1 --- */
// Komentar 2

void main()
{	
	char* s1 = "/* --- Nemojte me brisati! --- */";
	char* s2 = "// Nemojte ni mene!";
}
		
	
Slika 3. - Primer programskog koda koji može "prevariti" regularne izraze koje smo prethodno definisali.

.... koji jasno prikazuje da regularni izraz lako može biti "zbunjen", što nadalje znači da bi uklanjanje komentara preko prethodno definisanih regularnih izraza rezultiralo uklanjanjem (pravih) komentara, ali - takođe i uklanjanjem sadržaja niske s1 (koji iz perspektive regularnih izraza deluje kao komentar), a najveći problem bi bila niska s2 koja posle uklanjanja dela koda koji "deluje" kao linijski komentar (koji se završava prelaskom u novi red) - više ne bi bila terminisana!

U opštem smislu, redosled pozivanja regularnih izraza je i te kako bitan, međutim - u implementaciji kojom se bavimo - ne postoji redosled koji dovodi do rešenja!

.... ali, za trenutak ćemo se "praviti da to ne znamo", i pokušaćemo, u mislima - da 'zakrpimo' program.

Ako smo ustanovili da je u prethodnom slučaju problem bio u tome što smo preko regularnih izraza prvo tražili komentare - i nismo vodili računa o niskama, deluje da bi rešenje "moglo biti" da prvo tražimo niske (a tek posle niski komentare), i takav pristup bi u prethodnom primeru proizveo naizgled povoljan i naizgled korektan rezultat.

Sa druge strane, ako se prepravljenoj skripti preda drugi programski kod ....

		
#include<stdio.h>

/* --- "Niska 1" --- */
// Komentar 1

void main()
{	
	char* s1 = "/* --- Nemojte me brisati! --- */";
	char* s2 = "// Nemojte ni mene!";
}
		
	
Slika 4. - Primer programskog koda koji može "prevariti" regularni izraz koji je prepravljen tako da pravilno protumači programski kod sa prethodne slike (ali nije u stanju da pravilno tumači 'ostale' kodove).

.... niska "Niska 1" će rastaviti prvi blok komentar - tako da više neće biti moguće da se komentar prepozna na korektan način (niske /* --- i --- */ sada su niske koje će regularni izraz za prepoznavanje blok komentara - preskočiti), a budući da nema parsera koji će "zakrpiti" tri tokena * - delovi komentara ostaju (i pri tom nisu čak ni prepoznati kao komentar)!

* Najprostije bismo mogli reći - "bolje što je tako" (krenuli smo od ideje koja nije bila dobra od samog početka i stoga ne treba ni da pokušavamo da implementiramo parser koji bi "sanirao štetu").

Srećom, postoji elegantnije rešenje (koje ćemo prikazati).

Nije teško ('još jednom') doći do zaključka da problem nije u redosledu kojim se regularni izrazi pojavljuju, već - u tome što program ne vodi računa o kontekstu pri čitanju tokena (to jest, o tome da li se token koji se trenutno razmatra nalazi unutar komentara ili niske, ili izvan navedenih elemenata).

Uklanjanje komentara (uz vođenje računa o kontekstu)

Na ovom mestu vraćamo se na ideju sa kraja uvodnog članka.

Regularne izraze nećemo koristiti za direktno prepoznavanje niski i komentara ("u jednom koraku"), već, samo za prepoznavanje tokena koji označavaju početak i kraj komentara i niski.

Kada lekser podeli ulazni tekst na tokene (videćemo uskoro kako takva podela izgleda u praksi), "štafetu" preuzima jednostavan parser koji ćemo u nastavku implementirati.

U prepoznavanju konteksta pomoći će nam (prilično jednostavna) pravila C-olikih jezika koja se tiču pojave komentara u programskom kodu:

  • blok komentari počinju tokenom /* i završavaju se tokenom */
  • linijski komentari počinju tokenom // i završavaju se prelaskom u sledeći red

.... ali, postoje i pravila koja se tiču drugih tokena:

  • niske počinju i završavaju se znakom " (mogu naravno počinjati i znakom ' (apostrof), kao i ` (backtick), ali, u ovom članku - zarad jednostavnosti - zadržaćemo se samo na navodnicima)
  • znak " (navodnik), ne može se samostalno pojaviti unutar niske (koja počinje i završava se navodnicima), već isključivo kao deo escape sekvence: \"
  • unutar niske, ranije navedeni tokeni koji predstavljaju graničnike komentara - nemaju posebno značenje

Da bi programski kod bio pravilno protumačen, potrebno je uskladiti navedena pravila.

Pravila za tumačenje tokena

U praktičnom smislu, pravilno tumačenje programskog koda podrazumeva prepoznavanje konteksta * u kome se određeni token pojavljuje, i davanje prioriteta određenim pravilima - u odnosu na druga pravila (koja u određenom kontekstu imaju manji značaj):

  • u osnovnom kontekstu, pojava tokena " otvara kontekst čitanja niske, u kome pojava bilo kog tokena osim tokena " (koji zatvara kontekst čitanja niske) - nema posebno značenje (svi tokeni između dva znaka navoda - pripajaju se niski)
  • u osnovnom kontekstu, pojava tokena /* otvara kontekst čitanja blok komentara, u kome pojava bilo kog tokena osim tokena */ (koji zatvara kontekst čitanja blok komentara) - nema posebno značenje (svi tokeni između tokena /* i */ pripajaju se blok komentaru)
  • u osnovnom kontekstu, pojava tokena // otvara kontekst čitanja linijskog komentara, u kome pojava bilo kog tokena osim tokena \n (koji zatvara kontekst čitanja linijskog komentara) - nema posebno značenje (svi tokeni između tokena // i \n pripajaju se linijskom komentaru)

Osnovni zadatak je sledeći: uz korišćenje prigodnih regularnih izraza - pronaći u tekstu tokene //, \n, /*, */, ", ' (apostrof) i `(backtick) * - i zatim pravilno protumačiti u kom kontekstu se svaki od navedenih tokena pojavljuje.

* Smisao 'konteksta' u tumačenju programskog koda, objašnjen je u uvodnom članku.

** Iako smo već naveli da skripta (koju ćemo prikazati u članku), neće sadržati delove koda koji se tiču prepoznavanja niski koje su ograničene apostrofima i "bektikovima", verujemo da će velika većina čitalaca biti u stanju da samostalno implementira nedostajuće delove (ili korišćenjem sopstvenih ideja, ili po uzoru na delove koda koji se tiču prepoznavanja niski koje su ograničene navodnicima - koje ćemo prikazati i objasniti).

U nastavku (budući da se više "ne trudimo da niske i komentare prepoznamo odjednom"), pretvorićemo ulazni tekst u listu tokena u kojoj je svaki element:

  • jedan od (gore navedenih) specijalnih tokena (ili)
  • tekst koji se nalazi između dva relevantna tokena iz gore navedene grupe tokena (ili, tekst između početka ili kraja niske - i nekog od relevantnih tokena)

Pogledajmo primer.

Preko novog regularnog izraza ....

		
import re

regex_clike = "(//|\n|/*|*/|\")"

def rastavljanje_teksta(tekst, regex):
	lista = re.split(regex, tekst)
	return lista
		
	
Slika 5. - Regularni izraz za pronalaženje tokena koji predstavljaju granice niski i komentara.

.... dobija se sledeća lista (u pitanju je 'izdeljeni' izvorni kod sa slike #3):

		
#include<stdio.h>

-----------------------------
/*
-----------------------------
 --- Komentar 1 --- 
-----------------------------
*/
-----------------------------
//
-----------------------------
 Komentar 2
-----------------------------

void main()
{	
	char* s1 =
-----------------------------
"
-----------------------------
/*
-----------------------------
 --- Nemojte me brisati! --- 
-----------------------------
*/
-----------------------------
"
-----------------------------
;
-----------------------------
	char* s2 = 
-----------------------------
"
-----------------------------
//
-----------------------------
 Nemojte ni mene! 
-----------------------------

"
-----------------------------
;
-----------------------------

}
-----------------------------
		
	
Slika 6. - Lista koja se dobija kao rezultat rastavljanja teksta preko regularnog izraza sa prethodne slike.

.... i preostaje pitanje - kako takvu listu treba protumačiti.

Da bismo bolje razumeli kako treba rešiti zadatak, pogledajmo prvo nekoliko jednostavnijih primera ....

Uklanjanje komentara 01
Slika 7. - Uprošćeni primeri koje ćemo (u narednim odeljcima) koristiti pri upoznavanju sa pravilima za uklanjanje različitih kategorija tokena.

Slika sadrži četiri primera sa naredbama dodele u kojima su izdvojeni i ostali tokeni (operatori, white space znakovi i sl), što smo učinili da bi primeri bili zanimljiviji, ali, princip prepoznavanja niski i komentara se ne menja.

Primer #1

U prvom primeru ....

Uklanjanje komentara 02
Slika 8. - Primer prepoznavanja komentara - korak 1.

.... prvo se pojavljuju dva tokena koji ne menjaju kontekst čitanja.

Prvi token od značaja (token /*), uvodi čitač u režim prepoznavanja komentara ....

Uklanjanje komentara 03
Slika 9. - Primer prepoznavanja komentara - korak 2.

.... što znači da će svi tokeni do pojave tokena */ (uključujući i sam token */), biti prepoznati kao komentar.

Uklanjanje komentara 04
Slika 10. - Primer prepoznavanja komentara - korak 3.

U konkretnom primeru, ostatak naredbe je algebarski izraz u kome se pojavljuju: identifikator promenljive, i celobrojna vrednost.

Uklanjanje komentara 05
Slika 11. - Primer prepoznavanja komentara - korak 4.

U drugom primeru (koji je idejno sličan prvom), iskoristićemo priliku da se osvrnemo na različite opcije pri obradi prepoznatih tokena (koji predstavljaju delove niski ili komentara).

Primer #2

Prvi token od značaja (treći po redu, kao i u prvom primeru) ....

Uklanjanje komentara 06
Slika 12. - Primer prepoznavanja niske - korak 1.

.... uvodi čitač u režim prepoznavanja niski, što znači da će svi tokeni ....

Uklanjanje komentara 07
Slika 13. - Primer prepoznavanja niske - korak 2.

.... do pojave sledećeg tokena " (uključujući i sam token ") ....

Uklanjanje komentara 08
Slika 14. - Primer prepoznavanja niske - korak 3.

.... biti prepoznati kao deo niske.

Međutim (kao što smo već nagovestili), postoji nekoliko zanimljivih opcija u vezi sa raspoređivanjem tokena koji su prepoznati kao deo niske (ili deo komentara u nekom drugom primeru; ideja je istovetna).

Budući da postoje sve neophodne informacije, moguće je, po potrebi (ili po želji), grupisati tekstualni sadržaj niske u jedan token ....

Uklanjanje komentara 09
Slika 15. - Primer prepoznavanja niske - raspoređivanje prepoznatih tokena - ver. 1.

.... a druga mogućnost podrazumeva da se cela niska, zajedno sa navodnicima, smesti u jedan token:

Uklanjanje komentara 10
Slika 16. - Primer prepoznavanja niske - raspoređivanje prepoznatih tokena - ver. 2.

Postoji i treća opcija (koju smo već videli u primeru #1) - ostaviti tokene u originalnom rasporedu (i upravo tako ćemo i postupiti u skripti koju pišemo).

Uklanjanje komentara 11
Slika 17. - Primer prepoznavanja niske - raspoređivanje prepoznatih tokena - ver. 3.

Naravno, mnogi čitaoci mogu se zapitati - "zašto" (nećemo spajati komentare i niske)?!

Pre svega, treba se setiti čemu služi skripta koju pišemo, 🙂 a skripta služi - uklanjanju komentara, što znači da će svi delovi ulaznog teksta koji predstavljaju delove komentara - jednostavno biti zanemareni (odnosno, neće biti kopirani u izlaznu datoteku).

Što se tiče niski .... opet se treba setiti toga da će lista tokena, na kraju, ionako biti spojena u jednu nisku (tj. "običan tekst"). :)

Ali .... svakako je korisno znati da 'opcije postoje'.

Primer #3

Treći primer predstavlja složeniju situaciji, u tom smislu da se među tokenima pojavljuju: i tokeni koji otvaraju/zatvaraju komentare, i tokeni koji otvaraju/zatvaraju niske, a prvi token od značaja, token /* - uvodi čitač u režim prepoznavanja komentara (što znači da naredne tokene treba tretirati kao deo komentara) ....

Uklanjanje komentara 12
Slika 18. - Primer pravilnog tumačenja komentara koji sadrži nisku - korak 1.

Glavno pitanje je, šta će biti sa tokenom ", koji je prethodno imao poseban značaj ....

Uklanjanje komentara 13
Slika 19. - Primer pravilnog tumačenja komentara koji sadrži nisku - korak 2.

.... međutim, pravila su jasna i - u trenutnom kontekstu čitanja - token " nema poseban značaj, i biće prepoznat (samo) kao deo komentara.

Uklanjanje komentara 14
Slika 20. - Primer pravilnog tumačenja komentara koji sadrži nisku - korak 3.

U slučaju kada određeni token izvede čitač iz osnovnog režima (u konkretnom primeru, u pitanju je token /*), svi tokeni koji inače imaju posebno značenje (u drugim kontekstima), ali - u trenutnom kontekstu nemaju posebno značenje - postaju (praktično) obični tokeni, što znači da je jedini token od značaja - token koji vraća čitač u prethodni (osnovni) * režim.

Uklanjanje komentara 15
Slika 21. - Primer pravilnog tumačenja komentara koji sadrži nisku - korak 4.

(U konkretnom primeru, token */ vraća parser u prethodni/osnovni režim.)

* U drugim okolnostima (tj. 'inače'), "prethodni" režim i "osnovni" režim, ne moraju se poklapati (ali u gornjem primeru se poklapaju).

Primer #4

Četvrti primer (poslednji po redu), idejno je sličan prethodnom primeru, ali, situacija je 'obrnuta' (po pitanju pojave tokena /* ili ").

Token " uvodi čitač u režim prepoznavanja niske ....

Uklanjanje komentara 16
Slika 22. - Primer pravilnog tumačenja niske koja sadrži komentar - korak 1.

.... što (ponovo) znači da će određeni tokeni koji u osnovnom režimu imaju specijalno značenje - ali u trenutnom kontekstu nemaju posebno značenje ....

Uklanjanje komentara 17
Slika 23. - Primer pravilnog tumačenja niske koja sadrži komentar - korak 2.

.... biti prepoznati (samo) kao deo niske ....

Uklanjanje komentara 18
Slika 24. - Primer pravilnog tumačenja niske koja sadrži komentar - korak 3.

.... a isto važi i za preostale tokene (sve dok sledeći token " ne zatvori nisku).

Uklanjanje komentara 19
Slika 25. - Primer pravilnog tumačenja niske koja sadrži komentar - korak 4.

Ostaje da sve tehnikalije koje smo opisali, 'pretočimo' u funkcionalnu skriptu.

Implementacija

U implementaciji, poslužićemo se idejama koje smo razmotrili kroz nekoliko poslednjih primera, s tom razlikom što smo u primerima komentare označavali, a u skripti ćemo ih praktično uklanjati (to jest: deo teksta koji je prepoznat kao komentar, jednostavno neće biti kopiran u izlaznu datoteku).

Prvo ćemo precizno definisati opšta pravila za premeštanje tokena.

Pravila za premeštanje tokena

Pravila za premeštanje tokena usklađena su sa prethodno navedenim pravilima preko kojih se definiše smisao pojedinačnih tokena od posebnog značaja i njihovi međusobni odnosi:

  • preko steka, skripta vodi računa o kontekstu:
    • kontekst 0 - token koji se čita je van komentara i niski (u trenutku kada skripta nailazi na dati token)
    • kontekst 1 - token je deo linijskog komentara
    • kontekst 2 - token je deo blok komentara
    • kontekst 3 - token je deo niske
  • skripta prolazi redom kroz listu tokena
  • tokeni //, \n, /*, */ i " * menjaju (tj. 'mogu promeniti') kontekst na steku, ali, svi tokeni osim znaka navoda - uklanjaju se iz liste
  • ostali tokeni prate kontekst:
    • ako je kontekst 0 ili 3, token će biti ostavljen
    • ako je kontekst 1 ili 2, token će biti uklonjen (odnosno, neće biti kopiran)

* U nastavku, prikazaćemo skriptu, nakon čega ćemo dati i nekoliko uputstava za proširivanje (to jest, za dodavanje delova koji se tiču prepoznavanja ostalih tipova niski).

Python skripta za uklanjanje komentara iz programskog koda

		
# ----- konfiguracija ---------------------------------------- #
import re

datoteka_ulaz  = "naziv_datoteke"
datoteka_izlaz = "naziv_datoteke" # ista ili različita datoteka,
                                  # po vašem izboru
regex_clike  = "(//|\n|/*|*/|\")"
regex_python = "#.*\n"
regex_sql    = "--.*\n"
# ----- funkcije --------------------------------------------- #
def rastavljanje_teksta(tekst, regex):
	lista = re.split(regex, tekst)
	return lista
# ------------------- #
def obrada_pojedinacnog_tokena(token, stek, lista, nova_lista):
	kontekst  = stek[len(stek) - 1]
	if token == "": return

	if token == "/*":
		if kontekst == 0:
			stek.append(1)
			return
	
	if token == "*/":
		if kontekst == 1:
			stek.pop()
			return
	
	if token == "//":
		if kontekst == 0:
			stek.append(2)
			return
	
	if token == "\n" or token == "\r":
		if kontekst == 2:
			stek.pop()
			nova_lista.append(token)

	if token == "\"":
		if kontekst == 0: stek.append(3)
		if kontekst == 3: stek.pop()
	
	if kontekst == 0 or kontekst == 3:
		nova_lista.append(token)
# ------------------- #
def obrada_liste_tokena(lista):
	nova_lista = []
	stek       = [ 0 ]
	
	for token in lista:
		obrada_pojedinacnog_tokena(token, stek, lista, nova_lista)
	
	return nova_lista
# ------------------- #
def formatiranje_teksta(lista):
	s = ""
	for token in lista:
		s = s + token

	return s
# ----- obrada ----------------------------------------------- #
f = open(datoteka_ulaz, "rb")
s = f.read().decode("utf-8")
f.close()

lista = rastavljanje_teksta(s, regex_clike)
lista = obrada_liste_tokene(lista)
tekst = 

f = open(datoteka_izlaz, "wb")
f.write(s)
f.close()
		
	
Slika 26. - Kompletirana Python skripta za uklanjanje komentara iz programskog koda.

Ako skripti damo na obradu C kodove koje smo prethodno koristili, ovoga puta biće uklonjene samo niske koje predstavljaju komentar (tj. neće biti uklonjene niske koje samo "liče" na komentare).

Kao što smo ranije nagovestili, sledi nekoliko jednostavnih uputstva za proširivanje skripte (potrebno je da implementirate svega nekoliko ideja):

  • proširite regularni izraz koji je definisan na početku (tako da se u obzir uzmu znakovi ' i `)
  • definišite kontekst čitanja za preostale dve vrste niski (recimo: 4 za niske sa apostrofima i 5 za niske koje su definisane preko backtick-ova), i proširite funkciju obrada_pojedinacnog_tokena

Kada završite, obratite pažnju i na opšti kvalitet programskog koda: funkcija obrada_pojedinacnog_tokena je već sada na samoj granici po pitanju 'broja linija programskog koda', a ako se doda još nekoliko blokova - granica će biti pređena, i stoga preporučujemo definisanje zasebnih funkcija koje se tiču obrade pojedinačnih kategorija tokena (takve funkcije treba pozivati u okviru funkcije obrada_pojedinacnog_tokena).

Dodatne ideje za unapređenje skripte

Pošto proširite skriptu (shodno prethodno navedenim uputstvima), verujemo da ćete imati dovoljno sopstvenih ideja za dalje unapređivanje, ali, spomenućemo još jednu 'očiglednu' ideju.

Uklanjanjem linijskog komentara koji nije bio "slepljen" za početak reda (već je bio odvojen jednim ili više razmaka i/ili tabova), ostaće izvestan broj white space znakova, a uklanjanje blok komentara (koji su se prostirali u više redova), ostavlja prazne redove.

Shodno svemu što smo naveli (i kad smo već kod "ostavljanja"), ostavljamo vama - našim cenjenim čitaocima - da samostalno implementirate ideje koje smo naveli (i druge zanimljive i korisne ideje koje vama padaju na pamet). :)

U sledećem nastavku, bavićemo se prepoznavanjem regularnih izraza u JavaScript-u.

Autor članka Nikola Vukićević Za web portal codeblog.rs
Napomena: Tekstovi, slike, web aplikacije i svi ostali sadržaji na sajtu codeblog.rs (osim u slučajevima gde je drugačije navedeno) predstavljaju intelektualnu svojinu autora sajta codeblog.rs i zabranjeno je njihovo korišćenje na drugim sajtovima i štampanim medijima, kao i bilo kakvo drugo korišćenje u komercijalne svrhe, bez eksplicitnog pismenog odobrenja autora.
© 2020-2025. Sva prava zadržana.
Facebook LinkedIn Twitter Viber WhatsApp E-mail
početna > Članci > Tutorijal - Uklanjanje komentara iz programskog koda
codeBlog codeBlog
Sajt posvećen popularizaciji kulture i veštine programiranja.
Napomena: Tekstovi i slike na sajtu codeblog.rs (osim u slučajevima, gde je drugačije navedeno) predstavljaju intelektualnu svojinu autora sajta codeblog.rs i zabranjeno je njihovo korišćenje na drugim sajtovima i štampanim medijima, kao i bilo kakvo drugo korišćenje u komercijalne svrhe, bez eksplicitnog odobrenja autora.
© 2020-2025. Sva prava zadržana.
Facebook - logo
Instagram - logo
LinkedIn - logo
Twitter - logo
E-mail
Naslovna
   •
Uslovi korišćenja
   •
Obaveštenja
   •
FAQ
   •
Kontakt