private void parseInternalService() throws IOException, ParserException {
  if (!token.isKeyword("service")) {
    return;
  }
  getToken();
  assertToken(Scanner.TokenType.ID,"expected service name");
  String serviceName=token.content();
  getToken();
  eat(Scanner.TokenType.LCURLY,"{ expected");
  List<InterfaceDefinition> interfaceList=new ArrayList<>();
  OLSyntaxNode internalMain=null;
  SequenceStatement internalInit=null;
  boolean keepRunning=true;
  while (keepRunning) {
    if (token.isKeyword("Interfaces")) {
      getToken();
      eat(Scanner.TokenType.COLON,"expected : after Interfaces");
      boolean keepRun=true;
      while (keepRun) {
        assertToken(Scanner.TokenType.ID,"expected interface name");
        InterfaceDefinition i=interfaces.get(token.content());
        if (i == null) {
          throwException("Invalid interface name: " + token.content());
        }
        interfaceList.add(i);
        getToken();
        if (token.is(Scanner.TokenType.COMMA)) {
          getToken();
        }
 else {
          keepRun=false;
        }
      }
    }
 else     if (token.isKeyword("main")) {
      if (internalMain != null) {
        throwException("you must specify only one main definition");
      }
      internalMain=parseMain();
    }
 else     if (token.is(Scanner.TokenType.INIT)) {
      if (internalInit == null) {
        internalInit=new SequenceStatement(getContext());
      }
      internalInit.addChild(parseInit());
    }
 else     if (token.is(Scanner.TokenType.RCURLY)) {
      keepRunning=false;
    }
 else {
      throwException("Unrecognized token in inline service.");
    }
  }
  eat(Scanner.TokenType.RCURLY,"} expected");
  if (internalMain == null) {
    throwException("You must specify a main for internal service " + serviceName);
  }
  program.addChild(createInternalServicePort(serviceName,interfaceList));
  Program internalServiceProgram=new Program(getContext());
  for (  OLSyntaxNode child : program.children()) {
    if (child instanceof InterfaceDefinition || child instanceof OutputPortInfo || child instanceof TypeDefinition|| child instanceof TypeInlineDefinition|| child instanceof TypeDefinitionLink|| child instanceof TypeDefinitionUndefined) {
      internalServiceProgram.addChild(child);
    }
  }
  internalServiceProgram.addChild(new ExecutionInfo(getContext(),Constants.ExecutionMode.CONCURRENT));
  internalServiceProgram.addChild(createInternalServiceInputPort(serviceName,interfaceList));
  if (internalInit != null) {
    internalServiceProgram.addChild(new DefinitionNode(getContext(),"init",internalInit));
  }
  internalServiceProgram.addChild(internalMain);
  EmbeddedServiceNode internalServiceNode=new EmbeddedServiceNode(getContext(),Constants.EmbeddedServiceType.INTERNAL,serviceName,serviceName);
  internalServiceNode.setProgram(internalServiceProgram);
  program.addChild(internalServiceNode);
}

private void parseInternalService ( ) throws IOException , ParserException { if ( ! token . isKeyword ( "service" ) ) { return ; } getToken ( ) ; assertToken ( Scanner . TokenType . ID , "expected service name" ) ; String serviceName = token . content ( ) ; getToken ( ) ; eat ( Scanner . TokenType . LCURLY , "{ expected" ) ; List < InterfaceDefinition > interfaceList = new ArrayList < > ( ) ; OLSyntaxNode internalMain = null ; SequenceStatement internalInit = null ; boolean keepRunning = true ; while ( keepRunning ) { if ( token . isKeyword ( "Interfaces" ) ) { getToken ( ) ; eat ( Scanner . TokenType . COLON , "expected : after Interfaces" ) ; boolean keepRun = true ; while ( keepRun ) { assertToken ( Scanner . TokenType . ID , "expected interface name" ) ; InterfaceDefinition i = interfaces . get ( token . content ( ) ) ; if ( i == null ) { throwException ( "Invalid interface name: " + token . content ( ) ) ; } interfaceList . add ( i ) ; getToken ( ) ; if ( token . is ( Scanner . TokenType . COMMA ) ) { getToken ( ) ; } else { keepRun = false ; } } } else if ( token . isKeyword ( "main" ) ) { if ( internalMain != null ) { throwException ( "you must specify only one main definition" ) ; } internalMain = parseMain ( ) ; } else if ( token . is ( Scanner . TokenType . INIT ) ) { if ( internalInit == null ) { internalInit = new SequenceStatement ( getContext ( ) ) ; } internalInit . addChild ( parseInit ( ) ) ; } else if ( token . is ( Scanner . TokenType . RCURLY ) ) { keepRunning = false ; } else { throwException ( "Unrecognized token in inline service." ) ; } } eat ( Scanner . TokenType . RCURLY , "} expected" ) ; if ( internalMain == null ) { throwException ( "You must specify a main for internal service " + serviceName ) ; } program . addChild ( createInternalServicePort ( serviceName , interfaceList ) ) ; Program internalServiceProgram = new Program ( getContext ( ) ) ; for ( OLSyntaxNode child : program . children ( ) ) { if ( child instanceof InterfaceDefinition || child instanceof OutputPortInfo || child instanceof TypeDefinition || child instanceof TypeInlineDefinition || child instanceof TypeDefinitionLink || child instanceof TypeDefinitionUndefined ) { internalServiceProgram . addChild ( child ) ; } } internalServiceProgram . addChild ( new ExecutionInfo ( getContext ( ) , Constants . ExecutionMode . CONCURRENT ) ) ; internalServiceProgram . addChild ( createInternalServiceInputPort ( serviceName , interfaceList ) ) ; if ( internalInit != null ) { internalServiceProgram . addChild ( new DefinitionNode ( getContext ( ) , "init" , internalInit ) ) ; } internalServiceProgram . addChild ( internalMain ) ; EmbeddedServiceNode internalServiceNode = new EmbeddedServiceNode ( getContext ( ) , Constants . EmbeddedServiceType . INTERNAL , serviceName , serviceName ) ; internalServiceNode . setProgram ( internalServiceProgram ) ; program . addChild ( internalServiceNode ) ; }
parses an internal service , i . e . service service_name { }
