@@ -94,7 +94,7 @@ def __init__(self):
9494 self .terms = []
9595 self .annotations = []
9696
97- def accept (self , visitor ):
97+ def accept (self , visitor ):
9898 return visitor .visit_literal (self )
9999
100100 def signature (self ):
@@ -234,9 +234,11 @@ class AstPlan(AstNode):
234234 def __init__ (self ):
235235 super (AstPlan , self ).__init__ ()
236236 self .annotations = []
237+ self .dicts_annotations = None
237238 self .event = None
238239 self .context = None
239240 self .body = None
241+ self .args = [None ,None ]
240242
241243 def accept (self , visitor ):
242244 return visitor .visit_plan (self )
@@ -423,6 +425,7 @@ def __str__(self):
423425
424426
425427def parse_literal (tok , tokens , log ):
428+
426429 if not tok .token .functor :
427430 raise log .error ("expected functor, got '%s'" , tok .lexeme , loc = tok .loc )
428431
@@ -437,7 +440,6 @@ def parse_literal(tok, tokens, log):
437440 tok = next (tokens )
438441 tok , term = parse_term (tok , tokens , log )
439442 literal .terms .append (term )
440-
441443 if tok .lexeme == ")" :
442444 tok = next (tokens )
443445 break
@@ -897,29 +899,64 @@ def parse_event(tok, tokens, log):
897899 tok , event .head = parse_literal (tok , tokens , log )
898900 return tok , event
899901
902+ def create_dict_annotation (annotation ):
903+ """
904+ This function recieves a label as string and retuns a dictionary with the pred and annotations
905+ For instance:
906+ imput = "pred[annotation1(value1),annotation2(value2)]"
907+ output = {"pred": {"annotation": value1, "annotation2: value2}}
908+ If this function receives a label without annotations then will return a dictionary with the predicate
909+ For instance:
910+ imput = "pred"
911+ output = {"pred": {}}
912+ """
913+ if "[" not in annotation :
914+ key = annotation
915+ values = {}
916+ else :
917+ key = annotation .split ("[" )[0 ]
918+ values = annotation .split ("[" )[1 ].split ("]" )[0 ].split ("," )
919+ values = {v .split ("(" )[0 ]: int (v .split ("(" )[1 ].replace (")" ,"" )) if v .split ("(" )[1 ].replace (")" ,"" ).isdigit () else v .split ("(" )[1 ].replace (")" ,"" ) for v in values }
920+
921+ return {key : values }
900922
901923def parse_plan (tok , tokens , log ):
902924 plan = AstPlan ()
903-
904925 while tok .lexeme == "@" :
905926 tok = next (tokens )
906927 tok , annotation = parse_literal (tok , tokens , log )
907928 plan .annotations .append (annotation )
908929
930+ # Create a dict with the annotations of the label and add it to the plan
931+ dict_annotations = create_dict_annotation (str (annotation ))
932+ if plan .dicts_annotations is not None :
933+ raise log .error ("There are more than one label for one plan" )
934+ else :
935+ plan .dicts_annotations = dict_annotations
936+
909937 tok , event = parse_event (tok , tokens , log )
910938 plan .event = event
911939 plan .loc = event .loc
912940
941+ # If we find a () in the event this indicate that the trigger plan have arguments, we save them in plan.args[0]
942+ if "(" in str (event ):
943+ plan .args [0 ] = str (event ).split ("(" )[1 ].split (")" )[0 ]
944+
945+ # If we find a [] in the event this indicate that the trigger plan have annotations, we save them in plan.args[1]
946+ if "[" in str (event ):
947+ plan .args [1 ] = str (event ).split ("[" )[1 ].split ("]" )[0 ]
948+
949+
913950 if tok .lexeme == ":" :
914951 tok = next (tokens )
915952 tok , plan .context = parse_term (tok , tokens , log )
916953
917954 if tok .lexeme == "<-" :
918955 body_loc = tok .loc
919956 tok = next (tokens )
920-
921957 tok , plan .body = parse_plan_body (tok , tokens , log )
922958 plan .body .loc = body_loc
959+
923960
924961 return tok , plan
925962
@@ -1001,6 +1038,8 @@ def parse_agent(filename, tokens, log, included_files, directive=None):
10011038 return validate (agent , log )
10021039 else :
10031040 raise log .error ("expected 'include', or 'begin' or 'end' after '{', got '%s'" , tok .lexeme , loc = tok .loc )
1041+
1042+
10041043 elif tok .token .functor :
10051044 if last_plan is not None :
10061045 log .warning ("assertion after plan. should this have been part of '%s'?" , last_plan .signature (), loc = tok .loc )
@@ -1023,6 +1062,7 @@ def parse_agent(filename, tokens, log, included_files, directive=None):
10231062 agent .goals .append (ast_node )
10241063 elif tok .lexeme in ["@" , "+" , "-" ]:
10251064 tok , last_plan = parse_plan (tok , tokens , log )
1065+
10261066 if tok .lexeme != "." :
10271067 log .info ("missing '.' after this plan" , loc = last_plan .loc )
10281068 raise log .error ("expected '.' after plan, got '%s'" , tok .lexeme , loc = tok .loc , extra_locs = [last_plan .loc ])
@@ -1409,6 +1449,7 @@ def validate(ast_agent, log):
14091449 log .error ("plan head is supposed to be unifiable, but contains non-const expression" , loc = op .loc , extra_locs = [plan .loc ])
14101450
14111451 for annotation in plan .annotations :
1452+ # Warning annotations ignored
14121453 log .warning ("plan annotations are ignored as of yet" , loc = annotation .loc , extra_locs = [plan .loc ])
14131454
14141455 if plan .event .goal_type != GoalType .belief and plan .event .trigger == Trigger .removal :
@@ -1426,7 +1467,6 @@ def parse(filename, tokens, log, included_files=frozenset(), directive=None):
14261467
14271468def main (source , hook ):
14281469 log = agentspeak .Log (agentspeak .get_logger (__name__ ), 3 )
1429-
14301470 tokens = agentspeak .lexer .TokenStream (source , log , 1 )
14311471 agent = parse (source .name , tokens , log )
14321472
0 commit comments