[comp.lang.icon] reverse, ends of sentences

goer@SOPHIST.UCHICAGO.EDU (Richard Goerwitz) (11/21/89)

It looks to me as though you were trying to determine whether a given
string ends in a sequence normally associated with sentence-closure.
The best way to do this depends on the context in which you are pro-
gramming.  Are you, say, looking for an accurate sentence count in a
document?  If so, you will doutless want to use string scanning.  If
not, then a simple procedure like IsSentence might be invoked (its
main virtue is clarity, not speed):

procedure main()
  while line := !&input do {
    if IsSentenceEnd(line)
    then write("yes")
    else write("no")
    }
end
procedure IsSentenceEnd(str)
  punctuation := '\'"()[]?!.'
  shortstr := trim(str,punctuation)
  if upto('?!.',str,*shortstr+1)
  then return
end

In the context of string scanning, it is hard to use the reverse function.
Besides, I find that it tends to obfuscate code I write.  This might not
be true for you, but I find I have to think too hard about strings that
have been bent around backwards, especially when used for string scanning.
If you are processing whole texts, something like the following, though not ef-
ficient, will do nicely (if you are interested in efficiency, use C :-).
There are many things one could to to speed up the code, such as tabbing
provisionally up to periods, question marks, exclamations points.  Still
you get the point, I'm sure -

procedure main()
  count := 0; extrabit := ""
  while line := !&input do {
    if line == "" ~== extrabit then {
      write(string(count+:=1),":  ",extrabit)
      extrabit := ""
      next
      }
    else line := extrabit || line
    line ? {
      while sentence := TabSentence()
      do write(string(count+:=1),":  ",sentence)
      extrabit := tab(0)
      if extrabit[-1] ~== "-"
      then extrabit ||:= " "
      }
    }
end

procedure TabSentence()
  return {
    End2Front() ||
    tab(upto('!.?')+1) ||
    (tab(many('\'"()[]')) | &null, "") ||
    ((pos(0), "") | ="  ")
    }
end

procedure End2Front()
  suspend &subject[.&pos:&pos <- *&subject+1 to &pos by -1]
end