private static Instruction GetInstructions(ParserState state, Token previous) { Instruction inst = new Instruction(); do { if (state.PeepToken().Name == ",") { state.PopToken(); } Token open = state.PopToken(); if (open == null || open.Name != "(") { previous.ThrowException("Expected program format: (A1,G1),(A2,G2),...,(An,Gn)"); } Token a = state.PopToken(); if (a == null) { open.ThrowException("Expected action"); } if (a.Name == ")") { return(inst); } if (state.Action.ContainsKey(a.Name) == false) { open.ThrowException("Expected action"); } Token comma = state.PopToken(); if (comma == null || comma.Name != ",") { a.ThrowException("Comma should separate an action and a set of agents"); } MultiAgentLanguageModels.Action a1 = new MultiAgentLanguageModels.Action(a.Name); AgentsList g = GetAgentList(state); Token close = state.PopToken(); if (close == null || close.Name != ")") { a.ThrowException("Expected )"); } inst.Add(new Tuple <MultiAgentLanguageModels.Action, AgentsList>(a1, g)); } while (state.PeepToken() != null && state.PeepToken().Name == ","); return(inst); }
public static void ParseKeyword(ParserState state, Token firstToken) { switch (firstToken.Name) { case "initially": LogicElement le = EntryC1(state); Initially st = new Initially(le); state.Expression.Add(st); break; case "noninertial": ParseNoninertial(state, firstToken); break; case "by": Token action = state.TokenList[state.TokenList.Count - 1]; state.TokenList.RemoveAt(state.TokenList.Count - 1); AgentsList al = GetAgentList(state); if (al == null) { firstToken.ThrowException("Expected ']' at the end of agents list."); } Token t = state.PopToken(); if (t == null) { firstToken.ThrowException("Expected 'causes' or 'releases'."); } LogicElement result = null; if (t.Name == "releases") { Token fT = state.PopToken(); if (fT == null) { firstToken.ThrowException("Expected fluent after release."); } else if (!state.Fluent.ContainsKey(fT.Name)) { firstToken.ThrowException("Attempting to use undeclared fluent."); } result = state.Fluent[fT.Name]; } else if (t.Name == "causes") { result = EntryC1(state); } else { t.ThrowException("Expected 'causes' or 'releases'."); } if (t.Name == "releases" && (result is Fluent) == false) { t.ThrowException("Expected fluent after release."); } LogicElement condition = null; Token if_token = state.PeepToken(); if (if_token != null && if_token.Name == "if") { state.PopToken(); condition = EntryC1(state); } if (t.Name == "causes") { if (condition == null) { state.Expression.Add(new MultiAgentLanguageModels.Expressions.ByCauses( new MultiAgentLanguageModels.Action(action.Name), al, result)); } else { state.Expression.Add(new MultiAgentLanguageModels.Expressions.ByCausesIf( new MultiAgentLanguageModels.Action(action.Name), al, result, condition)); } } if (t.Name == "releases") { if (condition == null) { state.Expression.Add(new MultiAgentLanguageModels.Expressions.ByReleases( new MultiAgentLanguageModels.Action(action.Name), al, (Fluent)result)); state.Expression.Add(new MultiAgentLanguageModels.Expressions.ByCauses( new MultiAgentLanguageModels.Action(action.Name), al, new Or(result, new Not(result)))); } else { state.Expression.Add(new MultiAgentLanguageModels.Expressions.ByReleasesIf( new MultiAgentLanguageModels.Action(action.Name), al, (Fluent)result, condition)); state.Expression.Add(new MultiAgentLanguageModels.Expressions.ByCausesIf( new MultiAgentLanguageModels.Action(action.Name), al, new Or(result, new Not(result)), condition)); } } break; case "causes": MultiAgentLanguageModels.Action act = new MultiAgentLanguageModels.Action(state.TokenList[state.TokenList.Count - 1].Name); state.TokenList.RemoveAt(state.TokenList.Count - 1); LogicElement effect = EntryC1(state); Token if_exp = state.PeepToken(); if (if_exp != null && if_exp.Name == "if") { state.PopToken(); LogicElement con = EntryC1(state); state.Expression.Add(new CausesIf(act, effect, con)); } else { state.Expression.Add(new Causes(act, effect)); } break; case "releases": MultiAgentLanguageModels.Action act1 = new MultiAgentLanguageModels.Action(state.TokenList[state.TokenList.Count - 1].Name); state.TokenList.RemoveAt(state.TokenList.Count - 1); Token eff1 = state.PopToken(); if (eff1 == null) { firstToken.ThrowException("Expected fluent after release."); } else if (!state.Fluent.ContainsKey(eff1.Name)) { firstToken.ThrowException("Attempting to use undeclared fluent."); } Token if_expr = state.PeepToken(); if (if_expr != null && if_expr.Name == "if") { state.PopToken(); LogicElement con = EntryC1(state); state.Expression.Add(new ReleasesIf(act1, state.Fluent[eff1.Name], con)); state.Expression.Add(new CausesIf(act1, new Or(state.Fluent[eff1.Name], new Not(state.Fluent[eff1.Name])), con)); } else { state.Expression.Add(new Releases(act1, state.Fluent[eff1.Name])); state.Expression.Add(new Causes(act1, new Or(state.Fluent[eff1.Name], new Not(state.Fluent[eff1.Name])))); } break; case "if": firstToken.ThrowException("Unexpected 'if' token."); break; case "impossible": Token token = state.PopToken(); if (token == null) { firstToken.ThrowException("Expected action name."); } if (!state.Action.ContainsKey(token.Name)) { token.ThrowException("Unknown action name."); } MultiAgentLanguageModels.Action ac = new MultiAgentLanguageModels.Action(token.Name); Token key = state.PopToken(); if (key == null) { firstToken.ThrowException("Expected 'by' or 'if' token."); } AgentsList agentsList = null; if (key.Name == "by") { agentsList = GetAgentList(state); Token cond_st = state.PeepToken(); if (cond_st == null || cond_st.Name != "if") { state.Expression.Add(new ImpossibleBy(ac, agentsList)); } else { state.PopToken(); LogicElement c = EntryC1(state); state.Expression.Add(new ImpossibleByIf(ac, agentsList, c)); } } else if (key.Name == "if") { //Token cond_st = state.PopToken(); //if (cond_st == null || cond_st.Name != "if") //key.ThrowException("Expected if after the list of agents."); LogicElement c = EntryC1(state); state.Expression.Add(new ImpossibleIf(ac, c)); } else { firstToken.ThrowException("Expected 'by' or 'if' token."); } break; case "always": LogicElement cond = EntryC1(state); state.Expression.Add(new Always(cond)); break; case "not": Token act2 = state.TokenList[state.TokenList.Count - 1]; MultiAgentLanguageModels.Action actt = new MultiAgentLanguageModels.Action(act2.Name); state.TokenList.RemoveAt(state.TokenList.Count - 1); Token by = state.PopToken(); if (by == null || by.Name != "by") { firstToken.ThrowException("Expected 'by' after 'not'."); } AgentsList agents = GetAgentList(state); Token if_st = state.PeepToken(); if (if_st != null && if_st.Name == "if") { state.PopToken(); condition = EntryC1(state); foreach (Agent a in agents) { state.Expression.Add(new ImpossibleByIf(actt, new AgentsList() { a }, condition)); Output.Print($"{actt.Name} not by {a.Name} under cond {condition.ToString()}"); } } else { foreach (Agent a in agents) { state.Expression.Add(new ImpossibleBy(actt, new AgentsList() { a })); } } break; case "after": LogicElement observable = EntryC1(state); Token aft = state.PopToken(); if (aft == null || aft.Name != "after") { firstToken.ThrowException("Expected 'after' after logic expression."); } Instruction instr = GetInstructions(state, aft); After after_exp = new After(observable, instr); state.Expression.Add(after_exp); break; case "observable": LogicElement obs = EntryC1(state); Token after = state.PopToken(); if (after == null || after.Name != "after") { firstToken.ThrowException("Expected 'after' after logic expression."); } Instruction inst = GetInstructions(state, after); ObservableAfter obsAfter = new ObservableAfter(obs, inst); state.Expression.Add(obsAfter); break; } }