| << Prev | - Up - | Next >> |
NaiveParser.ozf: Grammatical ProcessingThe naïve recognizer processes sequences of categories and a rule replaces a subsequence by a single category. The naïve parser processes sequences of parser trees and replaces a subsequence of parse tree by a new parse tree constructed using the elements of this subsequence. In terms of processing, the recognizer and the parser differ in only two operations:
First, in the way a rule determines whether it matches a subsequence. We will abstract this operation as the function IsPrefix.
Second, in the function that maps a subsequence to its replacement. We will abstract this operation as the function MakeTree.
The standard technique for abstracting away from specific operations is to pass them as arguments. Functor NaiveParser.oz exports function MakeParser which takes 3 arguments: IsPrefix and MakeTree as described above, and Rules which is a list of grammar rules in the format:
o(cat:s subcat:[np vp]) MakeParser returns a parser, i. e. a function which takes a list of Words (a sequence of terminal categories) as input and returns the categories or parse trees (depending on MakeTree) that have been recognized.
functor
export MakeParser
import
CLO(closure:Closure) at 'x-ozlib://oz-kurs/naive/NaiveClosure.ozf'
ABS(newBag :NewBag ) at 'x-ozlib://oz-kurs/Abstract.ozf'
define
fun {MakeParser IsPrefix MakeTree Rules}
<NaiveParser Infer>
<NaiveParser MakeInferenceRule>
<NaiveParser Parse>
in
Parse
end
end First, the Rules are converted into inference RULES appropriate for module NaiveClosure.ozf. Then Parse computes the infential closure of the initial literal Words under this set of RULES. The result of Parse is the list of conclusions which are sequences consisting of a single element (a category for the recognizer, a parser tree for the parser).
RULES = {Map Rules MakeInferenceRule}
fun {Parse Words}
for Cats in {Closure [Words] RULES} collect:Collect do
case Cats of [C] then {Collect C} else skip end
end
end Now, we must transform a grammar Rule of the form rule(cat:s subcat:[np vp]) into an inference rule, i. e., a function that takes a sequence of Cats as input and returns a list where subsequences matching the Rule.subcat list have been replaced according to Rule.cat. This list will be accumulated in a Bag and the job of recognizing matching subsequences is performed by the auxiliary procedure Infer. Notice that Infer is passed Bag.put in order to accumulate new conclusions.
fun {MakeInferenceRule Rule}
fun {$ Cats}
Bag={NewBag}
in
{Infer nil Cats Rule Bag.put}
{Bag.toList}
end
end Finally, Infer is exactly as we defined it in Section 5.4.2, except that we invoke the more abstract MakeTree rather than the specific List.toTuple.
proc {Infer Prefix Suffix Rule PutConclusion}
if {IsPrefix Rule.subcat Suffix} then Args Rest Tree in
{List.takeDrop Suffix {Length Rule.subcat} Args Rest}
Tree = {MakeTree Rule Args}
{PutConclusion {Append {Reverse Prefix} Tree|Rest}}
end
case Suffix
of nil then skip
[] H|T then {Infer H|Prefix T Rule PutConclusion}
end
end| << Prev | - Up - | Next >> |