Citat:
a1234567: Nema veze, komentar je na kraju reda, tako da prvi desni # označava komentar
svi ostali, pa i ti u stringu, su levo od njega.
Pa i nije bas:
Code:
print "Primer koda" # Komentar pocinje ovde, # a ne ovde
Evo resenja koje obuhvata sve slucajeve, s objasnjenjem sta se tu tacno radi ... napominjem da je ovo bas osnovacko resenje, ali korisno da uvidis neke stvari koje se koriste u slicnim problemima (eksperti bi to odradili drugacije, ali o tom potom):
Code:
#!/usr/bin/python
import sys
for line in open(sys.argv[1], 'r').readlines():
line = line.rstrip()
q_single = False # Apostrof (')
q_double = False # Navodnik (")
escape = False # Backslash (\)
prev_char = '' # Pamti prethodni znak u redu
for pos,ch in enumerate(line):
if (q_single or q_double) and escape:
escape = not escape
continue
elif (q_single or q_double) and (ch == "\\"):
escape = not escape
continue
elif (ch == '"' and prev_char != "\\" and not q_single and not escape):
q_double = not q_double
elif (ch == "'" and prev_char != "\\" and not q_double and not escape):
q_single = not q_single
elif (ch == '#' and not q_single and not q_double):
line = line[:pos]
break
prev_char = ch
print line
Kao sto sam vec pomenuo, u ovom problemu moras da ispitas da li se taraba nalazi unutar string literala ("Ova # je unutar literala") ili ne ("Ovo je literal" # A ovo komentar). I kao sto sam ti vec predlozio gore, moras da skeniras znak po znak u svakoj liniji i da donosis odluku da li ti je trenutna pozicija "skenera" unutar ili van literala. U gornjem primeru smo definisali tri logicke promenljive, cije vrednosti menjamo u toku programa koristeci logiku:
Code:
var = False
...
var = not var
Ova klik-klak tehnika u programiranju, poput prekidaca, se inace naziva 'toggle'. Kad god prodjes kroz liniju 'var = not var', promenljiva var naizmenicno menja vrednost od True ka False i obrnuto. U ovom kontekstu toggle smo koristili kao indikator STANJA, odnosno moda. Kada naidjemo na navodnik ("), prolazimo kroz toggle (q_double = not q_double), cime menjamo stanje literala - ako smo bili van literala sada smo unutar i obrnuto. Znaci - kada naidjes na prvi navodnik, program smatra da je string literal zapocet, a kada ponovo naidjes na isti tip navodnika literal je zavrsen. Slicno vazi i za apostrof, za literale koji su oiviceni apostrofima koristimo toggle q_single. Ali recimo, navodnik (") unutar literala oivicenog apostrofima (npr. 'Ovaj znak " je unutra') ili obrnuto ("Ovaj znak ' je unutra") ne sme da se broji ni kao pocetak, ni kao kraj literala, vec kao njegov deo. Osnovni program bi znaci bio:
Code:
...
if (ch == '"' and not q_single): # Naisao je ", ali ne unutar literala oivicenog sa '
q_double = not q_double
elif (ch == "'" and not q_double): # Naisao je ', ali ne unutar literala oivicenog sa "
q_single = not q_single
...
Ostaje da resimo slucaj \" i \'. To su escape znaci, koriste se kada unutar literala koristis isti znak kojim se definisu granice literala - npr. "Rec \"google\" oznacava inace ...". Tu u igru vec ulazi pamcenje prethodnog znaka, za sta se koristi prev_char. Na kraju, najtezi slucaj je kada se pojavi \\ unutar literala, sto se u Pythonu koristi za sam backslash. Tu uvodimo i ovaj toggle escape kojim se taj slucaj resava.
Gornji primer je prost, ali resava konkretan deo sintakse Pythona (parsiranje komentara). Profesionalci koji pisu kompajlere ne rade to tako pesice. Parsiranje sintakse teskta je nauka za sebe, ali i nije neka visa matematika i fizika ... :-). Kao sto se vidi cak i u gornjem primeru, kljucni pojam je STANJE (namerno napisano velikim slovima) - biti unutar i van literala je primer stanja. Biti unutar for() ili while() petlje ili if() strukture je takodje primer stanja. Znaci, treba nam algoritam koji pamti stanje sistema i u zavisnosti koji karakter/slovo/rec/sta god ... dodje dok si u stanju X, sistem prelazi u stanje Y ili Z. Ta problematika je stara vec solidnih 60 godina, time su se bavili i Turing, kao i Moore i Mealy i naziva se teorija konacnih automata. (
Finite State Machines - FSM). Na
ovom blog postu lik je zaista lepo objasnio kako se FSM moze implementirati u Pythonu.
Medjutim, FSM je samo temelj price. Svakako da profesionalci ne prave FSM bas uvek od nule. Postoje gotovi alati za parsiranje sintakse - lex, yacc, bison, flex ... o njima mozes da procitas
ovde ako te zanima, ali to ti je vec masterclass nivo.
Ali ima i nesto sto mozes da savladas cak i na ovom nivou. Programeri ne prave kompajlere svaki dan ... osim ako se ne zovu Guido van Rossum :-). Obicnim smrtnicima - IT-sljakerima je mnogo potrebnije da parsiraju dokumente formatirane u nekom markup jeziku - HTML, SGML, XML ... Recimo, s nekog servera ti stize HTML tabela, sa sve onim <TD></TD> tagovima, a zelis da izdvojis podatke iz te tabele. Ili neki XML fajl, tipa: <TEMPERATURA>27</TEMPERATURA><PRITISAK>1000</PRITISAK> ... naravno, i to moze da se radi alatima opisanim gore, ali ljudi vise vole gotovanska prosta resenja. Srecom, ima tako nesto, zove se
BeautlfulSoup, koji ti omogucava da neki HTML ili XML dokument parsiras lako ... bs4 moze da koristi i apsolutni pocetnik. Eto ti ideje za neki naredni zadatak ...
[Ovu poruku je menjao B3R1 dana 04.03.2020. u 11:48 GMT+1]