home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / CLIPPER / MISC / BIPL.ZIP / PROCS.ZIP / SENTENCE.ICN < prev    next >
Encoding:
Text File  |  1992-09-28  |  4.5 KB  |  155 lines

  1. ############################################################################
  2. #
  3. #    File:     sentence.icn
  4. #
  5. #    Subject:  Procedure to generate sentences in file
  6. #
  7. #    Author:   Richard L. Goerwitz
  8. #
  9. #    Date:     June 3, 1991
  10. #
  11. ###########################################################################
  12. #
  13. #    Version:  1.2
  14. #
  15. ###########################################################################
  16. #  
  17. #  sentence(f)   - suspends sentences from file f
  18. #
  19. #  A lot of grammatical and stylistic analysis programs are predicated
  20. #  on the notion of a sentence.  For instance, some programs count the
  21. #  number of words in each sentence.  Other count the number and length
  22. #  of clauses.  Still others pedantically check for sentence-final par-
  23. #  ticles and prepositions.
  24. #
  25. #  This procedure, sentence(), is supposed to be used as a filter for
  26. #  ASCII text files, suspending everything that looks remotely like a
  27. #  sentence in them.
  28. #
  29. #  BUGS:  Cannot correctly parse sentences with constructs like "R. L.
  30. #  Goerwitz" in them.  The algorithm can be much improved simply by
  31. #  checking to see if the word after the period is in /usr/dict/words
  32. #  or whatever your system dictionary file is.  If it isn't, then it's
  33. #  likely not to be the beginning of a sentence (this also is not in-
  34. #  fallible, naturally).
  35. #
  36. ############################################################################
  37. #
  38. #  Requires:  co-expressions
  39. #
  40. ############################################################################
  41.  
  42.  
  43. procedure sentence(intext)
  44.  
  45.     local sentence, get_line, line, tmp_s, end_part, whole_thing
  46.     static inits, punct
  47.     initial {
  48.     inits := &ucase ++ &digits
  49.     punct := ".\"'!?)]"
  50.     }
  51.     sentence := ""
  52.     get_line := create read_line(intext)
  53.  
  54.     while line := @get_line do {
  55.  
  56.     # If we hit a blank line, it's a signal from read_line that we
  57.     # have encountered a change in the indentation level, and
  58.     # should call it a sentence break (though it could just be
  59.     # indentation for a quote, a section header, etc., it seems
  60.     # these all indicate major, sentence-like divisions in the
  61.     # text).
  62.     if line == "" then {
  63.         suspend sentence
  64.         sentence := ""
  65.         next
  66.     }
  67.  
  68.     # Go on until you can't find any more sentence-endings in line,
  69.     # then break and get another line.
  70.     repeat {
  71.  
  72.         # Scan for a sentence break somewhere in line.
  73.         line ? {
  74.  
  75.         # Ugly, but it works.  Look for sequences containing
  76.         # things like periods and question marks, followed by
  77.         # a space and another space or a word beginning with
  78.         # a capital letter.  If we don't have enough context,
  79.         # append the next line from intext to line & scan again.
  80.         if tmp_s := tab(upto(punct)) &
  81.             upto('!?.', end_part := tab(many(punct))) &
  82.             not (pos(-1), line ||:= @get_line, next) &
  83.             =" " & (=" " | (tab(many('\'"('))|&null,any(inits)))
  84.         # IF YOU WANT TO ADD A DICTIONARY CHECK, then read in
  85.         # a dictionary like /usr/dict/words, and then change
  86.         # any(inits) above to something like (any(inits),
  87.         # longstr(list_of_usrdictwords,map(&subject),&pos), =" ")
  88.         # where longstr() matches each string in list_of_usr-
  89.         # dictwords.
  90.         then {
  91.  
  92.             # Don't bother with little two-letter hunks.
  93.             whole_thing := sentence || tmp_s || end_part
  94.             if *whole_thing > 3 | find(" ",whole_thing)
  95.             then suspend whole_thing
  96.  
  97.             tab(many(' '))
  98.             line := tab(0)
  99.             sentence := ""
  100.             next
  101.         }
  102.         else break
  103.         }
  104.     }
  105.  
  106.     # Otherwise just tack line onto sentence & try again.
  107.     sentence ||:= line
  108.     }
  109.  
  110.     return sentence
  111.  
  112. end
  113.  
  114.  
  115.  
  116.  
  117. procedure read_line(intext)
  118.  
  119.     local new_line, ilevel, junk_count, space_count, line
  120.     static last_ilevel, blank_flag
  121.     last_ilevel := 0
  122.  
  123.     while line := trim(!intext,'\t ') do {
  124.  
  125.     # Check to see if line is blank; if so, set blank_flag.
  126.     if line == "" then
  127.         { blank_flag := 1; next }
  128.  
  129.     # Determine current indentation level.
  130.     detab(line) ? {
  131.         ilevel := *tab(many(' ')) | 0
  132.     }
  133.  
  134.     line ? {
  135.  
  136.         tab(many('\t '))
  137.  
  138.         # Signal the calling procedure if there is a change in the
  139.         # indentation level by suspending a blank line.
  140.         if (ilevel > last_ilevel) | (ilevel < last_ilevel, \blank_flag)
  141.         then suspend ""
  142.         last_ilevel := ilevel
  143.  
  144.         # Put a space on the end of line, unless it ends in a dash.
  145.         new_line := tab(-1) || (="-" | (move(1) || " "))
  146.         # Make sure the flag that indicates blank lines is unset.
  147.         blank_flag := &null
  148.     }
  149.  
  150.     # Suspend the newly reformatted, trimmed, space-terminated line.
  151.     suspend new_line
  152.     }
  153.  
  154. end
  155.