<< Prev | - Up - | Next >> |
The complete program of the concurrent parser below runs under Mozart 3.0.0 only.
declare
fun{RunAgenda agenda(initialize:Initialize
processInfo:ProcessInfo)}
local
Items
local
MailBox={Port.new Items}
in
proc {Post Item}
{Port.send MailBox Item}
end
end
local
proc{Process Agent Item Board}
case Item
of stop then raise done end
elseof info(Info) then
NewObjects = {ProcessInfo Agent Info}
in
{ForAll NewObjects
proc{$ O}
case O of agent(A) then {StartAgent A}
elseof info(I) then {Board.post info(I)}
end
end}
{Board.post infoProcessed}
else skip % other control items
end
end
in
proc{StartAgent Agent}
{Board.post newAgent}
thread
try {ForAll Board.items
proc {$ Item}
{Process Agent Item Board}
end}
catch done then skip end
end
{Show done}
end
end
in
Board = board(items:Items
post:Post
startAgent:StartAgent)
end
local
class WatcherState
attr
agents:0
infos:0
tasks:0
initialized:false
meth init skip end
meth initialized
initialized<-true
end
meth infoProcessed
tasks<-@tasks-1
end
meth newAgent
agents<-@agents+1
tasks<-@tasks+@infos
end
meth info(...)
infos<-@infos+1
tasks<-@tasks+@agents
end
meth done($)
{And @initialized @tasks==0}
end
end
in
proc{StartWatcher Board}
local
State={New WatcherState init}
in
proc{Process Item}
{State Item}
if {State done($)}
then
{Board.post stop}
raise done end
else
skip
end
end
end
in
thread
try {ForAll Board.items Process}
catch done
then skip
end
end
end
end
fun{FilterInfos Items}
case Items
of info(Info)|Is then Info|{FilterInfos Is}
elseof stop|_ then nil
elseof _|Is then {FilterInfos Is}
end
end
in
{StartWatcher Board}
{Initialize Board}
{Board.post initialized}
{FilterInfos Board.items}
end
fun{MakeAgenda Rules Lexicon Words}
fun{MoveDot Rule}
case Rule of rule(head:Head done:Done todo:Next|Todo dot:Index)
then rule(head:Head done:Next|Done todo:Todo dot:Index+1) end
end
fun{ProcessInfo Agent Edge}% computes new a info item or a new agent
% whenever possible by applying the
% dotted rule of the Agent to the Edge
fun{Create Pred Right}
if Agent.rule.todo.2==nil then
info(edge(left: Agent.left
right : Right
cat : Agent.rule.head
pred : Pred))
else
agent(edge(left:Agent.left
right:Right
rule:{MoveDot Agent.rule}
pred:Pred))
end
end
in
if Edge.left==Agent.right andthen
Edge.cat==Agent.rule.todo.1
then
{Map
{Search.allP
proc {$ Tree}
{Agent.pred Tree}
{Edge.pred}.head = Tree.args.(Agent.rule.dot)
end 1 _}
fun{$ Pred} {Create Pred Edge.right} end}
else
nil
end
end
proc{Initialize Board}
{List.forAllInd Words
proc {$ I Word}
{ForAll {Lexicon Word}
proc {$ Cat#Fun}
fun {Pred} root(head:{Fun} args:args) end
in
{Board.post info(edge(left:I right:I+1
cat:Cat pred:Pred))} end}
end}
{ForAll Rules
proc {$ Rule}
%% -- for each rule
case Rule of rule(Head Body Fun) then
N = {Length Body}
R = rule(head:Head done:nil todo:Body dot:1)
fun {Pred}
Args = {Tuple.make args N}
in
root(head:{Fun Args} args:Args)
end
in
{List.forAllInd Words
proc {$ I _}
%% -- for each position
{Board.startAgent edge(left:I right:I rule:R pred:Pred)}
end}
end
end}
end
in
agenda(initialize:Initialize
processInfo:ProcessInfo)
end
local
Dir='www.ps.uni-sb.de/~niehren/vorlesung/Programs/Functors/'
URL='http://'#Dir
[GrammarMod] = {Module.link [URL#'Grammar.ozf']}
in
Rules = GrammarMod.rules
Lexicon = GrammarMod.lexicon
end
fun{Parse Words}
Agenda = {MakeAgenda Rules Lexicon Words}
Edges = {RunAgenda Agenda}
{Browse Edges}
FullEdges ={Filter Edges fun{$ E}
{And E.left==1
E.right=={Length Words}+1}
end}
in
{Map FullEdges fun{$ E}
{E.pred}.head
end}
end
/*
declare Words = [john saw the man with the telescope]
{Browse {Parse Words}}
*/
If you want another Mozart version instead then you have to recompile the grammar functor and to use your new version. Here is the code of the grammar functor:
functor
export
Lexicon Rules
define
Lex =
lex(
the:
[det #fun {$} det(phon:the number:_) end]
a:
[det #fun {$} det(phon:a number:singular) end]
john:
[np #fun {$} np(phon:john number:singular) end]
man:
[n #fun {$} n(phon:man number:singular) end]
men:
[n #fun {$} n(phon:men number:plural) end]
woman:
[n #fun {$} n(phon:woman number:singular) end]
women:
[n #fun {$} n(phon:women number:plural) end]
'with':
[prep #fun {$} prep(phon:'with') end]
telescope:
[n #fun {$} np(phon:telescope number:singular) end]
saw:
[v #fun {$} v(phon:saw number:_) end]
sees:
[v #fun {$} v(phon:see number:singular) end]
likes:
[v #fun {$} v(phon:likes number:singular) end
n #fun {$} n(phon:likes number:plural ) end]
like:
[v #fun {$} v(phon:like number:plural) end]
)
fun {Lexicon Word} Lex.Word end
Rules =
[rule(s [np vp]
fun {$ Args}
Args.1^number=Args.2^number
s(Args.1 Args.2)
end)
rule(np [det n]
fun {$ Args}
Args.1^number=Args.2^number
np(number:Args.2^number Args.1 Args.2)
end)
rule(np [n]
fun {$ Args}
Args.1^number=plural
np(number:plural Args.1)
end)
rule(np [np pp]
fun {$ Args}
np(number:Args.1^number Args.1 Args.2)
end)
rule(vp [v np]
fun {$ Args}
vp(number:Args.1^number Args.1 Args.2)
end)
rule(vp [vp pp]
fun {$ Args}
vp(number:Args.1^number Args.1 Args.2)
end)
rule(pp [prep np]
fun {$ Args}
pp(Args.1 Args.2)
end)
rule(vp [v]
fun {$ Args}
vp(number:Args.1^number Args.1)
end)
]
end
<< Prev | - Up - | Next >> |